
近期 React 可谓是站在了风口浪尖上。某些大厂们纷纷开始抛弃它转而使用其他框架。但实际上,React 只手遮天的势力难以一时磨灭,我们这些小厂里的前端其实不必太过担心。真到了 React 末日的时候,这个世界也一定发生了巨变。所以,在当下,我们还是专注于当前,使用好 React. 于是我在这里总结了这大半年使用 React 的体验,主要是组件的生命周期和它常见的应用场景。
生命周期钩子方法
组件的挂载阶段
constructor
- 执行阶段:在开始
render之前。 - 在这里进行
state的初始化工作。但不要使用setState. - 还可以做一些事件绑定的工作。
- Note:
- 如果既不绑定事件也不初始化
state, 那么其实可以不使用consturctor. - 在少数情况下,
constructor中的state可以使用props来替代,但如果要达到状态随props改变的效果,最好使用状态提升来实现,因为state并不会随着props的改变而改变。
- 如果既不绑定事件也不初始化
1 | constructor(props){ |
componentWillMount
- 执行阶段: 组件将要挂载的阶段。在
render前调用,只会调用一次。 - 这里或许可以添加一些接口请求数据的逻辑,但在这里进行 state 的更新是异步的,它并不会触发
re-render也就是render重新渲染。通常情况下,更推荐使用constructor来替代. - Note: 如果要避免一些副作用,更好的办法是将这里面的逻辑放在
componentDidMount里来处理。
render
- 渲染挂载组件。这步一定会执行的。
- 在正常状态下,该方法会返回以下几种类型的值:
- React element: 最常见的返回。即使用
JSX创建的原生DOM或自定义的组件例如<MyComponent/>. - Protal: 使用
ReactDOM.createPortal方法创建的对象。 - Boolean:
bool && <div/>, 当bool为false的时候,不渲染。 - String|Number: 文本节点。
- null: 不渲染。
- React element: 最常见的返回。即使用
- Note:
- 该方法是纯函数,不应有
setState的操作。每次渲染只会输出同一个值。如果有对状态的变更,应该是放在componentDidMount里。 - 该方法是可以返回数组的,这样就可以返回多个对象。
- 该方法是纯函数,不应有
1 | render() { |
componentDidMount
- 组件挂载完毕时即调用。生命周期内只会调用一次。
- 应用场景:通常可以将请求后端数据—— ajax/fetch 放在这里。此时界面上
DOM已经存在。可以做有关DOM的操作。例如findDOMNode. - Note: 在这里调用
setState会进行一次额外的rendering,虽然这会导致两次的render, 但用户不会察觉这过度的时间。可能要多加考虑的地方是这会导致一定的性能问题。
componentWillUnmount
- 执行阶段:当组件卸载的时候的回调函数。
- 应用场景: 适用于清除定时器,取消请求等逻辑。
- Note: 这个函数回调适合销毁那些在
componentDidMount里创建的方法。
更新阶段
componentWillReceiveProps
componentWillReceiveProps(nextProps)- Note:
- 每次接收到新的
props调用。注意这里是接收到props就调用,但props的值不一定就和原来的值不一样,有可能还是相同的。在某些情况下,这会造成重复渲染。 - 在组件完全挂载后才会调用。在完全挂载之前是不会调用的。
- 可以在这里比较
props和nextProps, 然后更新state, 但setState不会触发该方法。
- 每次接收到新的
shouldComponentUpdate
shouldComponentUpdate(nextProps, nextState)- 当每次
props或state更新时调用。在首次render之后的每次render之前执行。 - Note:
- 该方法的返回值将会影响
componentWillUpdate、render、componentDidUpdate的执行。但在未来这一点有可能会改变。 - 可以在这里可以进行一些值是否相等的判断,但最好不要将对象,数组等判断放在这里,因为这可能会引起性能问题。
- 该方法的返回值将会影响
componentWillUpdate
componentWillUpdate(nextProps, nextState)shouldComponentUpdate方法返回true之后执行。- Note:
- 在这里不能调用
setState方法,也不能进行redux的action, 因为他会重复调用该方法。 - 如果需要在
state更新后操作props, 把这部分逻辑放在componentWillReceiveProps.
- 在这里不能调用
render
- 渲染挂载组件。
componentDidUpdate
componentDidUpdate(prevProps, prevState)- 在初次
render以后的每次渲染之后执行。执行逻辑和componentWillUpdate一样,当shouldComponentUpdate返回false时不会执行。 - 应用场景:该方法总是在
DOM存在后才会执行,所以可以在这里进行一些操作DOM的逻辑。也可以在这里发起一些网络请求,但前提props发生了更改,否则可能也会引起性能问题。
componentDidCatch (16版本引进)
componentDidCatch(err, info)- 捕捉异常。
try/catch固然很好,但它会立即捕获异常。在React中,有时我们虽然遇到错误,但不希望影响挂载或渲染过程。所以统一在这个回调里进行处理。对用户来说,业务仍然是正常的,错误维护了React的生态,并不会影响组件挂载。React组件都必须是纯函数,并禁止修改其自身 props.
这里以图片形式更直观地来理解这整个生命周期流程
- 组件的生命周期流程图

PS: 截止 9 月份,React 宣布将会随着 16 版本更新,修改原有的 license, 将原专利许可和 BSD 协议改为 MIT 协议。算是给这场风波一个较为圆满的结果。
参考:
1.react
2.reactchectsheet
3.reactjs
评论