React减少执行render函数

233 阅读2分钟

更新UI界面的一种方法是通过调用ReactDOM.render(),所以我们为了减少不必要的UI界面的更新,需要减少不必要的render函数执行。

我们知道在组件的prop和state发生变化的时候组件会执行render()函数,为了减少组件执行此函数,所以先掌握组件的生命周期,接下来从组件的第一次渲染 和 更新props或者state等方法触发更新操作。

生命周期函数入手

  • 在组件初次渲染的时候,执行

    • comonentWillMount();//只执行一次(除页面卸载重新执行)

    • render();

    • componentDidMount();//只执行一次(除页面卸载重新执行)

      如果嵌套组件那么初始化的时候,执行结果我们可以看出和Vue其实一样的。

      在挂载前先执行父组件的生命周期。挂载的时候先执行子组件。

  • 父子组件嵌套

    • 当父组件传人子组件props发生变化的时候,子组件执行componentWillReceiveProps 和 shouldComponentUpdate,如果shouldComponentUpdate返回false则后面的生命周期不会再执行,如果返回true,则执行componentWillUpdate->render()->componentDidUpdate

    • 所以为了不必要的渲染,则需要在shouldComponentUpdate方法中制止,pureComponent就是封装了shouldComponentUpdate方法,只是浅比较state和props。

    • 子组件的componentWillReceiveProps,只有当父组件传人的props值发生变化的时候才会执行。

从以上我们了解了一个减少组件执行render的方法。就是在组件内的shouldComponentUpdate方法内判断prop和state的变化然后返回true或者false,返回false组件不会执行后面的操作。

setState

当组件依赖的state获取prop发生变化会使得组件,先了解setState的用法。 在官方文档中有个“正确地使用 State”章节。

  • 不要直接修改 State this.state.comment = 'Hello'; 因为不会重新渲染组件。
  • State 的更新可能是异步的 --当在setState()方法传对象的时候 出于性能考虑,会把多个setState()调用合并成一个进行调用。所以不要直接依赖this.props和this.state的值来更新下一个状态(因为它们可能为异步更新)。
  • 解决state更新可能为异步的情况是在setState() 传人函数。 -- 一个函数代表同一批
    // Correct
    this.setState((state, props) => ({
      counter: state.counter + props.increment
    }));
    
  • State 的更新会被合并 调用setState的时候,会把传人的setState对象合并到当前的state中。
  • 当执行多个setState的时候,前面的setState可能会被后面的覆盖。 (时间比较短)
    • 解决方案:
      1. 将每次的setStae的操作放入宏任务队列中(比如setTimeout)。
      2. 放入setState的第二个参数内。(第二个参数是回调函数 是state更新后执行)
      3. setState()第一个参数传人函数(因为每传人一个函数为不同的一批)。

React更新到17 react.docschina.org/blog/2020/0… 我正将React15.6升级到React16.13。