更新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可能会被后面的覆盖。 (时间比较短)
- 解决方案:
- 将每次的setStae的操作放入宏任务队列中(比如setTimeout)。
- 放入setState的第二个参数内。(第二个参数是回调函数 是state更新后执行)
- setState()第一个参数传人函数(因为每传人一个函数为不同的一批)。
- 解决方案:
React更新到17 react.docschina.org/blog/2020/0… 我正将React15.6升级到React16.13。