React严格定义了组件的生命周期,生命周期有三个过程:
- 装载过程(Mount),组件第一次在DOM树中渲染的过程。
- 更新过程(update),组件被重新渲染的过程。
- 卸载过程(Unmount),组件从DOM中删除的过程。
在这三种不同的过程,React库会依次调用组件的一些成员函数,这些函数都称为生命周期函数。
一、装载过程
当组件第一次被渲染的时候,依次调用函数:
- constructor
- getInitialState
- getDefaultProps
- componentWillMount
- render
- componentDidMount
1.constructor
这也是ES6类的构造函数,但不是每个组件都需要定义构造函数,无状态的React组件就不需要定义构造函数。
React组件需要构造函数是为了:
- 初始化
state,因为组件生命周期中任何函数都可能要访问state,那么整个生命周期中第一个被调用的构造函数就是初始化state的最好地方。 - 绑定成员函数的
this环境。(ES6类的长远函数的this并不是和类实例自动绑定的,在构造函数中,this指向的就是当前实例组件,所以为了方便将来的调用,就在构造函数中将这个实例绑定给成员函数)
会有另外一种bind函数的方式:
this.foo = ::this.foo
等同于:
this.foo = this.foo.bind(this)
::操作符叫做bind操作符,虽然有babel插件支持这种写法,但不会成为ES标准语法,虽然很简洁,但并不推荐使用。
2.getInitialState 和 getDefaultProps
- 这两个方法只在
React.createClass方法创造的组件类才会用到,不适用于ES6类。 -
getInitialState是用来初始化组件的this.state,在ES6类中,在构造函数就已经完成对this.state的赋值以及初始化。 -
getDefaultProps是用来初始化组件的props,在ES6类中,通过给类的属性defaultProps赋值可以指定props的初始值。
3.render
-
render是React中最重要的函数,因为所有的React组件的父类React.Component类对除了render之外的生命周期函数都有默认的实现,所以一定要实现render函数。 -
render函数并不做实际的渲染动作,它只是返回一个JSX描述的结构,最终由React来操作渲染过程。 - 如果组件选择没有东西可渲染,可以让
render函数返回一个null或者false,就等于告诉React,这个组件这次不需要渲染任何DOM元素。 - render函数必须是一个纯函数,完全根据
this.state和this.props来决定返回的结果,而且不产生任何副作用。在render函数中去调用this.setState是错误的,因为一个纯函数不应该引起状态的变化。
4.componentWillMount 和 componentDidMount
- 在装载过程中,
componentWillMount会在调用render函数之前调用,componentDidMount会在调用render函数之前被调用。 - 通常都不会定义
componentWillMount函数,这里可以做的事情都可以提前到construction中去做。 -
componentDidMount不是紧跟着render函数被调用,而是当所有组件的render函数都被调用后,才会调用所有组件的componentDidMount。
二、更新过程
当组件被装载到DOM树上之后,用户在网页上可以看到组件的第一印象。如果要更好的用户体验,就要让该组件可以随着用户操作改变展现的内容。
当props是或者state被修改的时候,就会引发组件的更新过程。
更新过程会依次调用以下生命周期函数,其中render函数和装载过程一样:
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
1.componentWillReceiveProps(nextProps)
- 只要是父组件的
render函数被调用,在render函数里面被渲染的子组件就会经历更新过程,不管父组件传给子组件的props有没有改变,都会触发子组件的componentWillReceiveProps函数。 - 通过
this.setState方法触发的更新过程不会调用这个函数。
2.shouldComponentUpdate(nextProps, nextState)
-
shouldComponentUpdate函数是除了render函数在React组件周期中最重要的一个函数。 -
shouldComponentUpdate函数,决定了一个组件什么时候不需要渲染。 - 在更新过程中,React库会首先调用
shouldComponentUpdate函数,如果这个函数返回true,那就会继续更新过程,接下来调用render函数;如果得到false,那就立刻停止更新过程,也就不会引发后续的渲染了。 - 只要使用恰当,就能够大大提高
React组件性能。 - 如果要定义
shouldComponentUpdate,那就根据这两个参数,外加this.props和this.state来判断出是返回true还是false。
3.componentWillUpdate和componentDidUpdate
- 如果组件的
shouldComponentUpdate返回true,React接下来就会一次调用对应组件的componentWillUpdate、render和componentDidUpdate函数。 - 和装载过程的
componentWillMount和componentDidMount这对函数一样,把render函数夹在中间。 - 和装载过程不同的是,当在服务端使用
React渲染时,这一对Did函数,也就是componentDidUpdate函数,并不是只在浏览器端才执行的,无论更新过程发生在服务器端还是浏览器端,该函数都会被调用。 - 实际上,用
React做服务器端渲染时,基本不会经历更新过程,因为服务器只需要产出HTML字符串,一个转载过程就足够产出HTML了,所以正常情况下服务器端是不会调用componentDidUpdate函数,如果调用了,则说明程序有错误,需要改进。
三、卸载过程
-
React组件的卸载过程只涉及一个函数componentWillUnmount,当React组件要从DOM树上删除掉之前,对应的componentWillUnmount会被调用,所以这个函数适合做一些清理性的工作。 -
componentWillUnmount中的工作往往和componentDidMount有关,比如,在componentDidMount中用非React的方法创造了一些DOM元素,如果不管就会造成内存泄漏,那就需要在componentWillUnmount中把这些创造的DOM元素清理掉。














网友评论