React中一个组件就是一个状态机,在组件的生命周期中,随着组件props
或state
的改变,其DOM表现形式也会有所变化。React组件的生命周期分为:创建期、存在期、销毁&清理期,在生命周期的不同阶段,React提供了不同的处理函数(组件API),通过这些处理函数使我们能够实现对组件整个生命周期内的控制和处理。
1. 组件的生命周期概述
调用React.createClass()
方法创建组件的时候,我们会提供一个包含render
方法的对象,除此之外还可定义组件时包含其它的描述的生命周期方法,这些方法会在组件生命周期的不同阶段被调用。
如,我们可以像下面这样定义一个组件,并定义其生命周期的方法(lifecycle.html):
var App = React.createClass({ displayName: 'App', componentWillMount: function(){ // 初始化期,组件加载前调用 }, componentWillUpdate: function(){ // 存在期,组件状态改变后重新渲染前调用 }, render: function () { // 初始化期或存在期调用 return ( <h1>itbilu.com</h1> ) }, componentWillUnmount: function (){ // 销毁&清理期调用 } });
组件被定义后,随着组件实例第一次创建,组件生命周期也随之开始并进行创建期,创建组件实例时会有一系列方法被调用;创建完成后,组件进入存在期,在组件的存在期,随着组件的props
和state
的改变,又会有一些方法被调用;组件使用完成后,React会将组件从DOM中移除,这时组件进入销毁&清理期,这时会有唯一的一个方法被调用。
React组件提供了生命周期内访问组件的API,但它提供的方法非常简洁,仅提供了一些必要的方法。
下面是组件生命周期:创建期、存在期、销毁&清理期的介绍,及生命周期各个阶段所调用的方法。
2. 创建期
组件的实例化是指:组件被创建并被首次渲染时。每当组件被创建、首次渲染时,都会有一系列会被调用。
2.1 创建期调用的方法
当首次创建一个组件时,以下方法会被依次执行:
对于该组件类的后续应用,会有以下方法会被依次执行:
2.2 创建期调用方法的作用
getDefaultProps
getDefaultProps
方法只会被调用一次,该方法一般用于顶级组件(没有父组件的组件)进行处理,新建组件实例时这个方法会对返回实例设置默认的props
属性。
getInitialState
对于组件的每个实例来说,getInitialState
会被调用且只会调用一次。通过这个方法,可以初始化每个实例的state
。
注意:getDefaultProps
方法只在首次创建实时被调用,而getInitialState
在每次创建实例时都会被调用。调用getInitialState
方法时,已经可以访问this.props
属性。
componentWillMount
componentWillMount
会首次渲染(首次挂载)前被调用,通过这个方法可以在组件被render
前最后一次修改组的state
。
render
render
方法会创建一个虚拟DOM,即:组件的输出。render
是唯一一个必须的方法,该方法有以下几点要求:
- 只能通过
this.porps
和this.statu
访问数据 - 其返回值可以是:null、false或React组件
- 只能返回一个顶级组件
- 不能改变组件状态或DOM的输出
render
方法返回的是一个虚拟DOM,React会将它和真实DOM做比较,以判断是否需要对DOM进行修改。
componentDidMount
在render
调用成功且真实的DOM已经被渲染后,可以在componentDidMount
方法内部通过this.getDOMNode()
访问到它。
this.getDOMNode()
是原始DOM的钩子函数,当需要访问原始DOM属性,如:访问宽、高或运行JS时,可以将这些操作挂载到这个方法上。
3. 存在期
在组件的存在期,组件已经渲染好并且用户可以与它进行交互。当用户进行某些交互(如:点击鼠标、手指触碰或键盘输入等)后,用户的操作会改变组件的state
,这时会有新的state
流注入到组件树,这时会有一些方法会被触发,通过这些方法,我们可以对获得对DOM进行操作的机会。
3.1 存在期调用的方法
DOMstate
改变后,会有以下方法会被触发:
3.2 存在期调用方法的作用
componentWillReceiveProps
任何时候,当组件的props
属性被修改时(通过父件或组件引用),组件的componentWillReceiveProps
方法都会被调用,这时我们就获得了修改props
对象和更新state
的机会。
shouldComponentUpdate
shouldComponentUpdate
方法可以让我们进一步优化React的渲染速度。当我们确定组件不需要重新渲染新的props
或state
时,可以通过该方法返回false
,这样React就会跳过调用render
方法及之后的componentWillUpdate
和componentDidUpdate
方法。
这个方法是非必要的,大多数情况下不需要使用它,不恰当的使用可能会影响程序运行。应该在确认性能瓶颈后,合理使用,达到精确渲染的目的。
componentWillUpdate
这个方法与componentWillMount
方法类似,发生在组件在接收到新的props
或state
后,render
方法进行渲染之前。
注意:不能通过这个方法更新props
或state
,而应该在componentWillReceiveProps
中修改。
componentDidUpdate
与componentDidMount
方法类似,这个方法使我们可以修改已经渲染好的DOM。
4. 销毁&清理期
React每使用完一个组件,就需要将其从DOM中卸载并销毁,这时只有componentWillUnmount
一个函数会被调用,通过这个方法我们可以完成一些必要的销毁和清理工作。
componentWillUnmount
随着组件在DOM中的移除,其生命周期也随之结束。componentWillUnmount
会在组件被移除前被调用,这时我们可以有机会做一些清理工作,如:清除componentDidMount
中添加的任务等。