setState not working with forloop in react function

前端 未结 2 1400
萌比男神i
萌比男神i 2021-01-27 16:09

I am nesting two api calls inside componentDidMount, everything working fine, the only issue I have is the state do not update so I put some console logs to see what\'s going on

2条回答
  •  太阳男子
    2021-01-27 16:52

    As you can see the state of loaded never get updated

    Because the setState happens asynchronous (not immediately update), using console.log(this.state.loaded) like that won't work as expected, instead, you might use the setState callback as you did with the second fetch, like so:

    this.setState(
      {
        data: data,
        loaded: true,
        loading: false
      },
      () => {
        console.log('analysis done!');
        console.log(this.state.loaded);
      }
    );
    

    EDIT

    I think we should use Promise.all() to make it work, like this:

      componentDidMount() {
        this.setState({ loading: true });
        fetch('https://url-one.com', {
          headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*',
            'X-Spree-Token': 'xxx'
          }
        })
          .then(response => response.json())
          .then(responseJson => {
            console.log('fetch reviews done!');
            this.setState(
              {
                list: responseJson.reviews
              },
              () => {
                var obj = this.state.list;
                var data = [];
                var fetchArr = [];
                for (let i in obj) {
                  let promise = fetch('https://url-two.com', {
                    method: 'POST',
                    headers: {
                      Accept: 'application/json',
                      'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                      api_key: 'uuu',
                      data: obj[i].text
                    })
                  }).then(response => response.json());
    
                  fetchArr.push(promise);  // make an array of promises
                }
    
                Promise.all(fetchArr).then(values => {   //after all promises resolved, we'll receive an array of responseJson, we'll loop through it
                  values.forEach((responseJson, i) => { //for each responseJson, we push it to the data array
                    data.push({
                      review: obj[i].text,
                      analysis: responseJson.results * 100
                    });
                  });
                  // finally, we update state
                  this.setState(
                    {
                      data: data,
                      loaded: true,
                      loading: false
                    },
                    () => {
                      console.log('analysis done!');
                      console.log(this.state.loaded);
                    }
                  );
                });
              }
            );
          });
      }
    

提交回复
热议问题