ReactJS setState only works when nested inside set

2019-05-03 19:35发布

The issue: When I use this.setState and I output the state in the callback, it doesn't change at all but when I nest the setstate inside a setstate it will then work correctly.

Example: This doesn't work -

this.setState({
    data: newData
});

This does work -

this.setState({
    data: newData
}, () => {
    this.setState({
        data: newData
    });
});

Does this have something to do with the way react batches state updates?

This is the actual code in which the setstate doesn't work unless I nest it (I've tried commenting everything out in this function and using setState to set coursePage to null but it doesn't work unless it's nested):

cancelCPIndexChange(index){
  let temp = this.state.coursePages;
  this.hideEditingCoursePage(index);
  let canceledIndex = temp[index];
  temp = temp.slice(0, index).concat(temp.slice(index+1));
  temp = temp.slice(0, parseInt(canceledIndex.course_pageindex)-1).concat(canceledIndex).concat(temp.slice(parseInt(canceledIndex.course_pageindex)-1));
  this.setState({
    coursePages: temp
  }, () => {this.setState({
      coursePages: temp
    });
  });
}

This is another function on the same level as cancelCPIndexChanges that is able to modify the state of coursePages:

showEditingCoursePage(index){
  let temp = this.state.coursePages;
  temp[index].editingCoursePage = true;
  this.setState({
    coursePages: temp
  });    
}

These functions are in course.js. Both these functions are passed down to CoursePages.js and then to CoursePage.js.

2条回答
迷人小祖宗
2楼-- · 2019-05-03 19:48

According to: https://facebook.github.io/react/docs/component-api.html

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

(I've noticed this myself in the past)

I'm not 100% certain, but I'd guess that the second setState in your callback function is "flushing" the pending state transition before creating the second one.

I'm not clear on where you want to consume the new value of state? It ought to be in the render method where you can be sure it's been updated (As the state transition triggers the render). If you want to use it immediately after the setState you still have the reference to the value, so can use that directly.

查看更多
别忘想泡老子
3楼-- · 2019-05-03 20:03

As said setState behaves asynchronously. There are two ways you can access the newly updated state value before render

  1. Using a call back function for setState method

  2. Use componentDidUpdate method. Using nextState param you can access the latest state. But make sure you should use setState method inside that

查看更多
登录 后发表回答