访问组件中函数外部的react状态变量将打印为null



我有一个AutoHospitals组件,我试图在.then函数之外获取状态变量的值,但它正在打印null

这是this.state.retrievedmrnNumber正在打印的代码片段。

.then(response => {
console.log("Extracting mrnNumber from Hospitals API results")
console.log(response.data.mrnNumber);
let  retrievedMrnNo = response.data.mrnNumber;
this.setState({ retrievedmrnNumber: retrievedMrnNo});
console.log("Printing Retrieved mrn number from state");
console.log(this.state.retrievedmrnNumber);
})   

以下是上述.then函数之外的控制台日志语句,它正在打印null:

console.log("Outside of then function: Printing Retrieved mrn number from state");
console.log(this.state.retrievedmrnNumber);

如何在.then功能之外访问它?我的最终目标是使用这条线上的值:

selectedHospitals = [{label: this.props.value[0] && this.state.retrievedmrnNumber || 'Select'}]

完整组件代码如下:

export class AutoHospitals extends Component {
constructor(props) {
super(props);

this.state = {
value: '',
selectedHospitalValues: null,
selectedHospitals: [],
retrievedmrnNumber:null,
loading: false
};
this.onChange = this.onChange.bind(this);


}
onChange = (val) => {

this.setState({
value: val,
selectedHospitalValues: val
});
this.props.onChange(val)
};
fetchRecords() {

let url = 'myurl'
this.setState({
loading: true
});       
return axios
.get(url)
.then(response => {

let selectedHospitals;

if(this.props.value[0]){
console.log('this.props.value is DEFINED - Request has been EDITED!!!!')
// START: Logic to get MRN Number 

let hospitalIdtoRetrieveMRNNumber = this.props.value[0].hospitalId;
axios
.get('api/Hospitalses/'+hospitalIdtoRetrieveMRNNumber)
.then(response => {
console.log("Extracting mrnNumber from Hospitals API results")
console.log(response.data.mrnNumber);
let  retrievedMrnNo = response.data.mrnNumber;
this.setState({ retrievedmrnNumber: retrievedMrnNo});
console.log("Printing Retrieved mrn number from state");
console.log(this.state.retrievedmrnNumber);


})   
// END: Logic to get mrn Number 
console.log("Outside response block: Printing Retrieved mrn number from state");
console.log(this.state.retrievedmrnNumber);

selectedHospitals = [{label: this.props.value[0] && this.state.retrievedmrnNumber || 'Select'}]
//let selectedHospitals = [{label: this.props.value[0] && 'mrn # 1234' || 'Select'}]
}else {
console.log('this.props.value is UNDEFINED - it is a NEW  REQUEST');
}
this.setState({
loading: false
});       
if (this.props.value) {
this.props.value.forEach(e => {
selectedHospitals.push(response.data._embedded.Hospitalses.filter(hospitalSet => {

return hospitalSet.hospitalId === e.hospitalId
})[0])
})
}



this.setState({

selectedHospitals: response.data._embedded.Hospitalses.map(item => ({
label: (item.mrnNumber.toString()),
projectTitle: item.projectTitle,
hospitalId: item.hospitalId,
})),                    
selectedHospitalsValues: selectedHospitals
});
}).catch(err => console.log(err));


}


componentDidMount() {
this.fetchRecords(0)
}

render() {
return (
<div>
<Hospitalselect value={this.state.selectedHospitalsValues} options={this.state.selectedHospitals} onChange={this.onChange } optionHeight={60} /> 
<div className="sweet-loading" style={{ marginTop: '-35px' }}>
<ClockLoader
css={override}
size={30}
color={"#123abc"}
loading={this.state.loading}
/>
</div>               
</div>
);
}
}

这一切都是关于sync\async的。考虑以下两个例子:

对于完全异步的then(不允许任何等待(:

export const download = (url, filename) => {
fetch(url, {
mode: 'no-cors' 
/*
* ALTERNATIVE MODE {
mode: 'cors'
}
*
*/
}).then((transfer) => {
return transfer.blob();                // RETURN DATA TRANSFERED AS BLOB
}).then((bytes) => {
let elm = document.createElement('a');  // CREATE A LINK ELEMENT IN DOM
elm.href = URL.createObjectURL(bytes);  // SET LINK ELEMENTS CONTENTS
elm.setAttribute('download', filename); // SET ELEMENT CREATED 'ATTRIBUTE' TO DOWNLOAD, FILENAME PARAM AUTOMATICALLY
elm.click();                             // TRIGGER ELEMENT TO DOWNLOAD
elm.remove();
}).catch((error) => {
console.log(error);                     // OUTPUT ERRORS, SUCH AS CORS WHEN TESTING NON LOCALLY
})
}

使用await,其中响应变为sync:

export const download = async (url, filename) => {
let response = await fetch(url, {
mode: 'no-cors' 
/*
* ALTERNATIVE MODE {
mode: 'cors'
}
*
*/  
}); 
try {
let data = await response.blob();
let elm = document.createElement('a');  // CREATE A LINK ELEMENT IN DOM
elm.href = URL.createObjectURL(data);  // SET LINK ELEMENTS CONTENTS
elm.setAttribute('download', filename); // SET ELEMENT CREATED 'ATTRIBUTE' TO DOWNLOAD, FILENAME PARAM AUTOMATICALLY
elm.click();                             // TRIGGER ELEMENT TO DOWNLOAD
elm.remove();
} 
catch(err) {
console.log(err);
}   
}

等待示例可以作为匿名函数调用(希望正常调用也可以(:

(async () => {
await download('/api/hrreportbyhours',"Report "+getDDMMYYY(new Date())+".xlsx");    
await setBtnLoad1(false);
})();

我相信async axios.get函数的Promise在您调用selectedHospitals 中的状态值时尚未解析

尝试将回调函数传递给then语句的返回:

.then(response => {
console.log("Extracting mrnNumber from Hospitals API results")
console.log(response.data.mrnNumber);
handleRequest(response.data.mrnNumber);
console.log("Printing Retrieved mrn number from state");
console.log(this.state.retrievedmrnNumber);
})   

这里是可以使用setState:的回调

handleRequest(data) {
this.setState({ retrievedmrnNumber: data});
}

EDIT要将句柄请求正确绑定到此,请尝试将其设置为箭头函数:

handleRequest = (data) => this.setState({retrievedmrnNumber:data});

最新更新