浅谈setState

  在设置组件的属性时我们都知道,一般把固定不变的属性设置放在props上,把会实时发生变化的属性放在state上,那么怎么样才能改变这个变化的属性值呢,我们用到这个函数,即setState。

  • setState不会立刻改变React组件中的state的值。
  • setState通过引发组件的一次更新过程来引发重新绘制。
  • 多次setState函数调用产生的结果会合并。

  以上是关于setState的关键三点,接下来详细阐述。

  首先是setState不会立刻改变React组件中state的值。其实,写到这有一个问题是为什么我们不能直接修改this.state的值,而是要用过setState的方法来修改呢。原因是this.state是一个对象,单纯的修改这个对象的值是没有意义的,我们想要做的是让页面重新渲染,所以需要一个函数去更改状态,当setState函数被调用时,能驱动组件的更新过程,引发componentDidUpdate、render等一系列函数的调用。

  举例子说明setState不会立刻改变React组件中state的值。

function incrementMultiple() {
  this.setState({count: this.state.count + 1});
  this.setState({count: this.state.count + 1});
  this.setState({count: this.state.count + 1});
}

  按以往的代码逻辑来理解,count属性应该是被修改了三次,但是实际上由于setState并不能立刻的修改this.state,获取到的this.state.count一直是最开始的那个值,总的来说,只变化了一次。接着我们将要思考的是到底什么时候修改这个state。

  setState通过引发一次组件的更新过程来引发重新绘制。引起React更新生命周期函数的4个函数,比修改props时少了一个componentWillReceiveProps函数。分别是:

  1. shouldComponentUpdate    // this.state没有更新呢
  2. componentWillUpdate     // this.state还没有更新呢
  3. render   // render被调用,开始更新了,如果shouldComponentUpdate函数返回的是false,更新中断,render就不会被调用,依然会更新this.state???
  4. componentDidUpdate

  最后一条,多个setState函数调用会产生合并:

function updateName() {
  this.setState({FirstName: 'Morgan'});
  this.setState({LastName: 'Cheng'});
}

  这个时候setState会有一个merge的过程。

  总结下来,setState的一个很令人头疼的地方就是不能立刻修改this.state的值,程墨先生在他的文章中提出this.setState可以接受函数作为参数,解决了这个问题。

function increment(state, props) {
  return {count: state.count + 1};
}

同样是修改state,但是这个时候来源不一样了,不再是this.state,而是重新获取的输入的参数state。

function incrementMultiple() {
  this.setState(increment);
  this.setState(increment);
  this.setState(increment);
}

React每次调用increment时,state都已经合并了之前的状态修改结果,this.state.count的值最后变成了3。

在increment函数被调用时,this.state并没有被改变,依然要等到render函数被重新执行时(或者shouldComponentUpdate函数返回false之后)才被改变。此处不是很懂。。。

 

学习这篇文章之后的笔记。

posted @ 2018-02-23 16:23  程澄  阅读(275)  评论(0编辑  收藏  举报