React组件的生命周期
挂载阶段
此阶段组件被创建,执行初始化,并被挂载到 DOM 中,完成组件第一次渲染。
挂载阶段
constructor
constructor
本身是 ES6 的class
的构造方法,组件被创建时,会首先调用组件的构造方法。这个构造方法会接受一个 props 参数,props 是从父组件传过来的属性对象,如果父组件没有传入属性而组件自身定义了默认属性,那么这个props
指向的就是组件的默认属性。
而且很关键的是,你必须在这个方法中先调用super(props)
才能保证props
被传入组件中,这部分具体的大家参照 ES6 中class
相关内容就可以了。
constructor
通常用于初始化组件的state
以及绑定事件处理函数等。
componentWillMount
该方法在组件被挂载到 DOM 前调用,且只会被调用一次。这个方法实际上很少被用到,相关阶段的处理完全可以放到constructor
中。
在这个方法中调用
this.setState
不会引起组件的重新渲染。
render
该方法是组件定义时唯一必要的方法(组件的其他生命周期函数都可以忽略)。在这个方法中,根据组件的props
和state
返回一个React
元素,用于描述组件的 UI,通常React
元素使用JSX
语法定义。
需要注意的是,render
并不负责组件的实际渲染工作,它只是返回了一个 UI 的描述,真正的渲染出页面 DOM 的工作是由React
自身负责。render
是一个纯函数,在这个方法中不能执行任何有‘副作用’
的操作,所以不能在 render 方法中调用this.setState
,这会改变组件的状态,导致程序出现问题。
componentDidMount
在组件被挂载到 DOM 后将会调用这个方法,且只会被调用一次。这个时候已经可以获取到 DOM 结构,因为依赖 DOM 节点的操作可以放到这个方法中。这个方法通常还会用于向服务器请求数据。在这个方法中调用 this.setState 会引起组件的重新渲染。
更新阶段
组件被挂载到 DOM 后,组件的props
和state
可以引起组件更新。props
引起的组件更新,本质上是由渲染该组件的父组件引起的,也就是当父组件的render
方法被调用时,组件会发生更新过程。这个时候,组件的props
的值是否变更是由父组件来决定的,但是,无论props
是否变化,父组件render
方法每被调用一次,都会导致组件更新。
state 引起的更新过程,是通过调用this.setState
修改组件的state
来触发的。
更新阶段
componentWillReceiveProps(nextProps)
看名称也可以猜到,这个方法和props
有关。这个方法只会在 props 引起的组件更新过程中,才会被调用。State
引起的组件更新并不会触发该方法。方法的参数nextProps
是父组件传递给当前组件的新的props
。在前面我们也提到过,父组件 render 方法的调用并不能保证传递给子组件的 props 发生变化,也就是说nextProps
不一定发生变化,因为往往我们需要先比较nextProps
和this.props
来决定是否执行props
发生变化后的逻辑。比如根据新的props
来更新state
触发组件的重新渲染。
在
componentWillReceiveProps
中调用setState
,只有在组件render
及其之后的方法中,this.state
指向的才是更新后的state
。在render
之前的方法(shouldComponentUpdate
、componentWillUpdate
)中,this.state
依然指向更新前的 state
通过调用
setState
更新组件状态并不会触发componentWillReceiveProps
的调用,否则可能会进入死循环,componentWillReceiveProps
->this.setState
->componentWillReceiveProps
->this.setState
-> ……
shouldComponentUpdate(nextProps, nextState)
这个方法决定组件是否继续执行更新过程。当方法返回 true 时(true 也是这个方法的默认返回值),组件会继续更新过程;当方法返回 false 时,组件的更新过程将停止,后续的componentWillUpdate
、render
、componentDidUpdate
也不会被调用。
一般通过比较nextProps
、nextState
的组件当前的props
、state
决定这个方法的返回结果。这个方法可以用来减少组件不必要的渲染,从而优化组件的性能。
componentWillUpdate(nextProps, nextState)
这个方法在组件 render 调用前执行,可以作为组件更新发生前执行某些工作的地方,一般也较少用到。
shouldComponentUpdate
和componentWillUpdate
中都不能调用setState
,否则会引起循环调用问题,render
永远无法被调用,组件也就不能被更新了。
componentDidUpdate(prevProps, prevState)
组件更新后调用,可以作为操作更新后的 DOM 的地方,这个方法的两个参数prevProps
和prevState
代表组件更新前的props
和state
。
卸载阶段
该过程是组件从 DOM 中被卸载的过程,该过程只有一个生命周期方法:componentWillUnmount
componentWillUnmount
这个方法在组件被卸载前调用,可以在这里执行一些清理工作,比如清除组件中使用的定时器,清除componentDidMount中
手动创建的 DOM 元素等,以避免引起内存泄露。
结语
上面我们简单梳理分析了React
组件的生命周期方法的不同阶段的执行过程,以及每个生命周期方法的功能的作用。最后要提醒大家,只有类组件才具有生命周期方法,函数组件是没有生命周期方法的。
参考资料:
React 中文文档
《React 进阶之路》
- 本文作者:冷星
- 本文链接:http://lengxing.club/2018/12/04/React%E7%BB%84%E4%BB%B6%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!