美文网首页
React组件的生命周期(16.3以前)和setState AP

React组件的生命周期(16.3以前)和setState AP

作者: JRG_Orange | 来源:发表于2017-10-21 11:53 被阅读0次

    最近看了程墨的几篇文章,对setState这个API有了更加深入的认识,下面总结一下。
    先回顾一下React组件的生命周期。

    一、组件的生命周期

    组件生命周期
    在挂载期首先会调用componentWillMount(),然后会接着触发render()渲染到页面,最后调用componentDidMount(),在卸载前会调用componentWillUnmont(),然后卸载组件。
    在组件更期时(此处指以props改变为例),首先会从父组件传来props,触发钩子函数(hook)componentWillReceiveProps()(若是state改变不会触发),然后触发shouldComponentUpdate(),如果shouldComponentUpdate()函数返回false,这时候更新过程就被中断了,render函数也不会被调用了,这时候React不会放弃掉对this.state的更新的,所以虽然不调用render,依然会更新this.state。若返回的是true,就会紧接着触发componentWillUpdate(),接着触发render(),更新组件的渲染,最后触发触发componentDidUpdate(),组件卸载和上述流程一样。

    二、setState()介绍

    引用网上的说法:

    React抽象来说,就是一个公式
    [图片上传失败...(image-cfb7ee-1531880117865)]

    setState是React用来更新state的一个API,用得越多,发现setState()有很多让人入坑的地方:

    1. 使用setState()一般情况下(后面会介绍特殊情况)不会立即更新state的值;
    2. setState通过引发一次组件的更新过程来引发重新绘制;
    3. 多次setState函数调用产生的效果会合并。

    对于第一点,引用网上的例子:

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

    上面的函数运行时,似乎对state.count的值加了3次,但实际上只加了一次,原因正是setState不会立即改变state的值所以后面两次的this.state其实还是最初的state。

    第二点需要提到上面的组件更新期的声明周期,setState调用引起的React的更新生命周期函数4个函数:

    • shouldComponentUpdate()
    • componentWillUpdate()
    • render()
    • componentDidUpdate()

    当shouldComponentUpdate函数被调用的时候,this.state没有得到更新。
    当componentWillUpdate函数被调用的时候,this.state依然没有得到更新。

    直到render函数被调用的时候,this.state才得到更新。

    (或者,当shouldComponentUpdate函数返回false,这时候更新过程就被中断了,render函数也不会被调用了,这时候React不会放弃掉对this.state的更新的,所以虽然不调用render,依然会更新this.state。)
    所以setState一般不会立即更新state的值,知道render()函数触发。

    对于第三点可以简单理解为:
    连续调用了两次this.setState,但是只会引发一次更新生命周期,不是两次,因为React会将多个this.setState产生的修改放在一个队列里,缓一缓,攒在一起,觉得差不多了再引发一次更新过程。这样做的好处是,不用每次setState就去触发一次render(),这样太消耗性能。

    另外setState()可以接受一个函数作为参数,也就是说可以在里面参入回调函数:

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

    值得注意的是:同样是把状态中的count加1,但是函数increment的状态的来源不是this.state,而是输入参数state,所以加1是累加上去的。
    值得一提的是,在increment函数被调用时,this.state并没有被改变,依然,要等到render函数被重新执行时(或者shouldComponentUpdate函数返回false之后)才被改变。这也就是说如果, this.setState(increment)中插入 this.setState({count: this.state.count + 1})会让前面的努力白费。如下:

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

    在几个函数式setState调用中插入一个传统式setState调用(嗯,我们姑且这么称呼以前的setState使用方式),最后得到的结果是让this.state.count增加了2,而不是增加4,所以不宜混用两种发法。

    更详细请点击原文参考

    相关文章

      网友评论

          本文标题:React组件的生命周期(16.3以前)和setState AP

          本文链接:https://www.haomeiwen.com/subject/eqxyuxtx.html