react学习笔记(12) - 生命周期中使用setState以及生命周期中的性能优化
React学习笔记 - 生命周期中使用setState以及生命周期中的性能优化
1. 生命周期中使用setState
- 一般来讲是不推荐在生命周期钩子中使用
setState,因为每一次使用setState就意味着数据更新,页面的重新渲染,页面重新渲染就会使得某些生命周期重新执行一遍,也就是说,在某些生命周期钩子(componentWillUpdate,shouldComponentUpdate)中使用setState会使组件陷入死循环,而新的生命周期钩子中(getSnapshotBeforeUpdate,以及getDerivedStateFromProps)则无法使用setState,因为这两个钩子都需要静态引用(加上前缀static),也就是说这两个钩子没有this指向,但是他们提供了一些形参来让你获取最新的state或者props数据
因此要想了解在生命周期中如何使用
setState,就需要下面的分析了!
一. 首先我们需要了解一下React生命周期的成员以及它们的执行流程:

React生命周期可以分为两条执行流程:
初始化:初始进入页面 →
constructor→componentWillMount(getDerivedStateFromProps[新]) → render →componentDidMount→componentWillUnmount;数据更新:
setState→componentWillReceiveProps(getDerivedStateFromProps[新]) →shouldComponentUpdate→componentWillUpdate[旧,后续可能会被取消] →render→getSnapshotBeforeUpdate[新,取代componentWillUpdate]→componentDidUpdate→componentWillUnmount。
- 更新流程需要提到两点:一点是
componentWillReceiveProps中使用setState,state会被收集储存起来,这里是区别于上面componentWillMount中state合并到初始数据中的。这里提一下:shouldComponentUpdate如果return=>false,则不会执行更新(render)。
1. 初始化

1、首先,进入页面,会初始化页面数据(
state,props,context等…),等待备用;2、然后,设置 生命状态 为:
MOUNTING,这个状态下面会说明它的用途,这里我们先按照流程继续往下走;3、接下来,在
componentWillMount中,setState操作,只是把state合并到初始化状态中,而根本不会触发render;在这里更新state,就等同于直接写在this.state中,所以,在此生命周期中的setState根本没有意义;4、执行到这里,生命状态 会被重置为
null,之后是渲染页面(即执行render);5、最后,渲染完以后,执行
componentDidMount,这里使用setState即会正常触发重新渲染了,更新state。(接下来,就是更新流程了!!)
2. 数据更新

1、首先,
react会比较前后元素、状态等是否不同,如果不同则正式发起更新;2、然后,生命状态 被设置为
RECEIVE_PROPS(注意:此时生命周期中,setState不会触发更新,而是会做其他处理);3、接下来,
componentWillReceiveProps中的setState就不会执行更新,而是合并挂载起来,等待render时统一更新;4、到这里,生命状态 会重置为null;然后
shouldComponentUpdate中会判断是否更新;之后是componentWillUpdate。
注意:
shouldComponentUpdate和componentWillUpdate执行的时候,生命状态 已经被重置为null,在它们里面的setState会触发更新,那么在其间使用呢?会造成什么?答案就是:在一个更新周期还没有render之前,再次发起updateComponent,直接导致递归更, 也就是死循环,由此可见,在这两个生命周期钩子中是禁止使用setState的
5、最后,渲染页面;再执行
componentDidUpdate;它里面执行setState,会触发更新,不同的是render完成之后再发起的reRender。虽然这儿区别于上面两个生命周期中使用的情况,但是会一遍一遍的更新,这肯定也是不合理的,所以需要有条件的使用setState。
总结:
生命周期中setState的使用情况:
- 无意义使用:
componentWillMount,componentWillUnmount; - 有条件使用:
componentDidUpdate; - 禁止使用:
componentWillUpdate,shouldComponentUpdate; - 正常使用:
componentWIllReceiveProps,componentDidMount。
生命周期中setState是否触发更新:
componentWillMount和componentWillReceiveProps中,setState会被react内部处理,而不触发render;其他生命周期均正常出发更新渲染。
生命周期中的性能优化
- 一般看来讲,生命周期中的性能优化一般有两种方法:第一种是手动优化,就是之前博客提到的生命周期钩子中,
shouldComponentUpdate的使用,通过我们手动对比判断通信传递中的状态数据是否前后一致,一致则组件不需要重新渲染一边
// 更新时:生命周期1: shouldComponentUpdate(nextProps, nextState):用于性能优化 |
- 第二种就是
React中内置的智能对比传输前后数据状态,PureComponent,它会自动的帮你 比较新props跟 旧的props, 新的state和老的state(值相等,或者对象含有相同的属性、且属性值相等 ),决定shouldcomponentUpdate返回true或者false, 从而决定要不要呼叫render function。但是要注意如果你的你的state或props『永远都会变』,那PureComponent并不会比较快,因为shallowEqual也需要花时间。
// 使用方法,在引入React组件时直接引入PureComponent取代Component即可 |






