React 组件的生命周期函数是我们在开发过程中经常用到的,是必须掌握的基础知识,如果有不熟悉的可以看官方文档,简单总结如下:
组件的生命周期函数分为两类:挂载或卸载过程 / 组件更新时。
1.挂载或卸载过程涉及到三个函数,这些函数都只会在组件初始化或者卸载时运行一次。
- componentWillMount - 组件即将挂载
- componentDidMount - 组件挂载完成
- componentWillUnmount - 组件即将卸载
2.组件更新时涉及到四个函数:
- componentWillReceiveProps - 组件即将接收新的 props(这个比较特殊,只适用于给组件传递新的参数时)
- shouldComponentUpdate - 判断组件是否需要更新,这个函数很重要,在父组件重新渲染,但是子组件不需要重新渲染的情况下,只有这个生命周期函数去判断子组件是否需要重新渲染,以优化程序,提高执行效率。
- componentWillUpdate - 组件即将更新
- componentDidUpdate - 组件完成更新
setState 更是基础的不能再基础的知识了,用来更新组件的状态。需要注意的是 setState 是一个异步方法,一个生命周期内所有的 setState 方法会合并操作。
但是如果把组件的生命周期和 setState 放在一起看就会有一连串的问题:生命周期函数里可以 setState 吗?什么时候 setState 合适呢?阅读完《深入React技术栈》第一和第三章,得出以下心得:
- 在 componentWillMount 中执行 setState 是无意义的,应该将这里的 setState 放到初始化 this.state 的地方去(如 constructor)直接作为 state 的初始值。原因是组件只挂载一次,在 componentWillMount 里 setState 会但是仅会更新 state 一次,而且会和 constructor 里的初始化 state 合并执行,因此这是无意义的 setState。
- 在 componentDidMount 中执行 setState 会导致组件在初始化的时候就触发了更新,渲染了两遍,应该尽量避免。有一些场景,比如在组件 DOM 渲染完成后获得DOM元素位置或者宽高等等 设置为 state,会不得在 componentDidMount 之后 setState,但是除了这些必要的时候,都应该尽量避免在 componentDidMount 里 setState。
- 在 componentWillUnmount 中执行 setState 不会更新 state,是不生效而且无意义的。
- 禁止在 shouldComponentUpdate 和 componentWillUpdate 中调用 setState,这会造成循环调用,直至耗光浏览器内存后崩溃。了解了生命周期之后,这条很好理解。在 shouldComponentUpdate 或者 componentWillUpdate 里调用 setState 会再次触发这两个函数,然后在两个函数又触发了 setState,然后再次触发这两个函数…… 这样就进入了一个不停 setState 然后不停触发组件更新的死循环里,会导致浏览器内存耗光然后崩溃。[具体分析可以看书的第3章]
- 在 componentDidUpdate 中执行 setState 会导致组件刚刚完成更新,又要再更新一次,连续渲染两遍(和在 componentDidMount 中执行 setState 类似)。因此如非必须,应该尽量避免。
- 在 componentWillReceiveProps 中可以 setState,不会造成二次渲染。由于只有 props 的变化才会触发 componentWillReceiveProps 事件,因为在这个事件里 setState 不会造成不停触发组件更新的死循环,可以放心在这个函数里 setState。
生命周期函数里 setState 的时机可以总结为以下表格: