Как сделать вызов axios только после того, как изменено состояние реакции? - PullRequest
0 голосов
/ 23 ноября 2018

Значение состояния реакции this.state.condition передается вызову axios, но this.state.condition видоизменяется только при второй попытке выполнения функции generateReport(), поэтому this.state.condition передается как пустой массиввызов axios при первой попытке выполнения функции generateReport().Есть ли обходной путь или решение проблемы?Код приведен ниже.

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;

    }

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Причина неожиданного поведения заключается в том, что this.setState () является асинхронным и не выполняется немедленно, как ожидается.В этом случае, когда setState () вызывается один за другим, не гарантируется, что первый setState () выполняется раньше следующего.Кроме того, реагирует на попытки объединить максимально возможные вызовы setState () в один за счет уменьшения повторного рендеринга виртуального DOM и поиска изменений.

Итак, в этом случае, когда мы хотим, чтобы операции были синхронными, мы можем передать обратный вызов, который будет выполнен после успешного выполнения 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, если ничего не выбрано, на случай, если оно не обработано.потому что ваше состояние будет установлено на обработку навсегда, как это было установлено в первой строке ранее.

Надеюсь, это решит проблему.Пожалуйста, прокомментируйте в случае каких-либо проблем:)

0 голосов
/ 23 ноября 2018

ваше состояние настройки, в то время как вы также проверяете состояние, так что вы получаете непредсказуемый вывод, который является неправильным.вставьте свою логику в обратный вызов 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"})
    })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...