仅在反应状态突变后,如何进行axios调用?

时间:2018-11-23 03:18:14

标签: javascript reactjs asynchronous axios

反应状态值this.state.condition被传递给axios调用,但是this.state.condition仅在第二次执行函数generateReport()时才发生突变,因此{{ 1}}作为空数组传递给第一次执行函数this.state.condition的axios调用。是否有任何解决方法或解决方案? 代码如下。

generateReport()

2 个答案:

答案 0 :(得分:0)

您的设置状态同时还检查条件,因此您得到的是不可预测的输出,这是错误的。将您的逻辑放在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"})
    })
}

答案 1 :(得分:0)

发生意外行为的原因是因为 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条件。因为您的状态将被设置为永久处理,就像之前的第一行一样。

希望这可以解决问题。如有任何问题,请发表评论:)