我有一个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});