[英]How to make the axios call only after the react state is mutated?
反应状态值this.state.condition
传递给axios
调用,但是this.state.condition
仅在第二次尝试执行函数generateReport()
时才发生突变,因此this.state.condition
作为空数组传递在第一次尝试执行函数generateReport()
调用axios调用。 是否有任何解决方法或解决方案? 代码如下。
generateReport(){
this.setState({statusMsg: ""});
this.setState({loaderInitialStatus:"Processing..."})
//this.isReq() ?
console.log('this.state.selectedOption???',this.state.selectedOption);
if(this.state.selectedOption && this.state.selectedOption.length > 0) {
let groups = []
this.state.selectedOption.map((item) => {
groups.push(item.value);
})
this.setState(prevState => ({
condition: [...prevState.condition, { name: "readByGroup", operator: "IN ", value: groups }]
}))
}
console.log('this.state.condition???', this.state.condition);
this.props.getMetricsByContent(this.state.condition).then((data) => {
this.setState({isLoader: false});
if(data && Array.isArray(data) && data.length > 0){
let csvContent = papa.unparse(data);
this.download(csvContent, 'metrics.csv', 'text/csv;encoding:utf-8');
this.setState({statusMsg: "File Downloaded successfully"})
} else this.setState({statusMsg: "No records to download"})
})
//: null;
}
您在设置状态的同时还要检查条件,因此得到了不可预测的输出,这是错误的。 将您的逻辑放在setState
回调中
请输入以下代码:
generateReport(){ this.setState({statusMsg:"", loaderInitialStatus:"Processing..."}, this.callBack) } callBack=()=>{ console.log('this.state.selectedOption???',this.state.selectedOption); if(this.state.selectedOption && this.state.selectedOption.length > 0) { let groups = [] this.state.selectedOption.map((item) => { groups.push(item.value); }) this.setState(prevState => ({ condition: [...prevState.condition, { name: "readByGroup", operator: "IN ", value: groups }] })) } console.log('this.state.condition???', this.state.condition); this.props.getMetricsByContent(this.state.condition).then((data) => { this.setState({isLoader: false}); if(data && Array.isArray(data) && data.length > 0){ let csvContent = papa.unparse(data); this.download(csvContent, 'metrics.csv', 'text/csv;encoding:utf-8'); this.setState({statusMsg: "File Downloaded successfully"}) } else this.setState({statusMsg: "No records to download"}) }) }
发生意外行为的原因是因为this.setState()是异步的 ,并且不会像预期的那样立即执行。 在这种情况下,如果一个接一个地调用setState(),则不能保证第一个setState()在下一个之前执行。 另外,react尝试通过减少虚拟DOM重新呈现和查找更改来将最大可能的setState()调用组合到其中。
因此,在这种情况下,我们希望操作是同步的,我们可以传递一个回调,该回调将在setState()成功后执行。
generateReport(){
const { selectedOption } = this.state;
if(selectedOption && selectedOption.length > 0) {
let groups = []
selectedOption.map((item) => {
groups.push(item.value);
})
this.setState(currStaleState => ({
statusMsg: "", loaderInitialStatus:"Processing...",
condition: [...currStaleState.condition, { name: "readByGroup", operator: "IN ", value: groups }]
}), () => {
this.props.getMetricsByContent(this.state.condition).then((data) => {
this.setState({isLoader: false});
if(data && Array.isArray(data) && data.length > 0){
let csvContent = papa.unparse(data);
this.download(csvContent, 'metrics.csv', 'text/csv;encoding:utf-8');
this.setState({statusMsg: "File Downloaded successfully"})
} else this.setState({statusMsg: "No records to download"})
})
})
} else {
console.log('error : no option selected');
}
}
另外,我合并了所有看起来独立的setState()调用。 另外,如果没有选择任何内容,以防万一,则应设置else条件。 因为您的状态将被设置为永远处理,就像之前的第一行一样。
希望这能解决问题。 如有任何问题,请发表评论:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.