组件的生命周期
2018-08-29 本文已影响7人
Lia代码猪崽
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
、rende
r和componentDidUpdate
函数。 - 和装载过程的
componentWillMount
和componentDidMount
这对函数一样,把render
函数夹在中间。 - 和装载过程不同的是,当在服务端使用
React
渲染时,这一对Did
函数,也就是componentDidUpdate
函数,并不是只在浏览器端才执行的,无论更新过程发生在服务器端还是浏览器端,该函数都会被调用。 - 实际上,用
React
做服务器端渲染时,基本不会经历更新过程,因为服务器只需要产出HTML
字符串,一个转载过程就足够产出HTML
了,所以正常情况下服务器端是不会调用componentDidUpdate
函数,如果调用了,则说明程序有错误,需要改进。
三、卸载过程
-
React
组件的卸载过程只涉及一个函数componentWillUnmount
,当React
组件要从DOM
树上删除掉之前,对应的componentWillUnmount
会被调用,所以这个函数适合做一些清理性的工作。 -
componentWillUnmount
中的工作往往和componentDidMount
有关,比如,在componentDidMount
中用非React
的方法创造了一些DOM
元素,如果不管就会造成内存泄漏,那就需要在componentWillUnmount
中把这些创造的DOM
元素清理掉。