生命周期对react非常重要,对很多新手来说,搞不懂哪个阶段该做什么事情,迷茫,乱用函数,导致性能下降,死循环.
文章主要记录了react平时常用的生命周期函数,及平时开发遇到的注意事项,自从react v16.3更新后,其生命周期还是发生很大的改变, 这里介绍v16.3之前的版本
React 生命周期主要包括三个阶段:
1. 初始化阶段
2. 运行中阶段
3. 销毁阶段
(注:结合图来看文章有助理解)
1. 初始化阶段
1-1.设置组件默认属性
方法一 挂载组件的时候设置 props(比较常用)
var data = [{title: 'Hello'}];
<Hello data={data} />
方法二 defaultProps
在组件内部定义,此方法编译才生效,es6 会报错,使用es7以上(详情)
static defaultProps = {
age: 18
}
在组件外部属性定义
Greeting.defaultProps = {
name: '我是props的默认值!'
};
ReactDOM.render(
<Greeting />,
document.getElementById('example')
);
1-2.组件的初始化状态 state
constructor(props){
super(props); // 不加super(),导致了this的 Reference Error
this.state={};
}
super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
super(props):传递props作为super()的参数,那就是你需要在构造函数内使用this.props
1-3.componentWillMount
因为componentWillMount是在render之前执行,所以在这个方法中setState不会发生重新渲染(re-render),通常情况下,推荐用constructor()方法代替.
提示: 很多时候喜欢这里去做一些初始化数据的请求,你会发现数据还没请求到就渲染render()了,当请求到数据后setState再渲染出数据.依然重复渲染. 建议初始化数据都在componentDidMount()中使用,新版本将去掉这个函数.
1-4.render
该方法会创建一个虚拟DOM,用来表示组件的输出。对于一个组件来讲,render方法是唯一一个必需的方法。render方法需要满足下面几点:
- 只能通过 this.props 和 this.state 访问数据(不能修改)
- 可以返回 null,false 或者任何React组件
- 只能出现一个顶级组件,不能返回一组元素
- 不能改变组件的状态
- 不能修改DOM的输出
render方法返回的结果并不是真正的DOM元素,而是一个虚拟的表现,类似于一个DOM tree的结构的对象。
1-5. componentDidMount
一般情况在这里做初始化异步数据请求
- 这个方法会在render()之后立即执行;
- 这里可以对DOM进行操作,这个函数之后ref变成实际的DOM
2. 组件运行阶段
此时组件已经渲染好并且用户可以与它进行交互,比如鼠标点击,手指点按,或者其它的一些事件,导致应用状态的改变,你将会看到下面的方法依次被调用
2-1.componentWillReceiveProps
组件的 props 属性可以通过父组件来更改,这时,componentWillReceiveProps 将来被调用。可以在这个方法里更新 state,以触发 render 方法重新渲染组件。
componentWillReceiveProps: function(nextProps){
if(nextProps.checked !== undefined){
this.setState({
checked: nextProps.checked
})
}
}
2-2.shouldComponentUpdate(nextProps, nextState)
在接收新的props或state时确定是否发生重新渲染,默认情况返回true,表示会发生重新渲染
注意
- 这个方法在首次渲染时或者forceUpdate()时不会触发;
- 这个方法如果返回false, 那么props或state发生改变的时候会阻止子组件发生重新渲染;
- 目前,如果返回false, 那么componentWillUpdate(nextProps, nextState), render(), componentDidUpdate()都不会被触发;
2-3.componentWillUpdate
在props或state发生改变或者shouldComponentUpdate(nextProps, nextState)触发后, 在render()之前.
千万不要在这个函数中调用this.setState()方法,死循环.结合图表看.
2-4.render
同上 1-4
2-5.componentDidUpdate(object prevProps, object prevState)
这个方法和 componentDidMount 类似
3.componentWillUnmount
组件被销毁时触发。这里我们可以进行一些清理操作,例如清理定时器, 关闭抽屉弹框,取消Redux的订阅事件等等.
总结对比
生命周期实例 demo