React组件的生命周期分为三个阶段:
- 组件初始化 Mounting
- 组件运行时 Updating
- 组件卸载时 Unmounting
Mounting — 组件初始化
- constructor():组件被创建时,首先被调用的方法,通常用来初始化组件state以及绑定事件处理方法,
该方法中不能调用setState()
,该构造方法接受一个props参数,必须在方法中首先调用super(props)才能保证props被传入组件中。 - componentWillMount():组件渲染之前调用,只会被调用一次。
在这个方法里setState不生效,不会触发re-render,而是会进行state合并。
实际开发中很少用这个方法,因为都可以放到constructor()中来处理,而且新版react已经弃用并认为该方法是legacy(老式的)不安全的。 - render():这是定义组件时唯一必要的方法,负责渲染真正的DOM。它是个纯函数,不能用来执行任何有副作用的操作,
所以不能在render中执行setState
,这会改变组件的状态。 - componentDidMount():组件渲染后调用,只会被调用一次,这个时候组件已经被挂载,组件已经生成对应的DOM结构,需要操作DOM可以在这个时期。同时也是从远端取数据,发送ajax请求,设置监听,定时任务的好地方。
这里可以setState。
Updating — 组件运行时
- componentWillReceiveProps(nextProps):只会在外部props变化时才会调用,state变化不会调用。
这里可以setState(),但是不会触发re-render,而是会进行state合并。
方法的参数nextProps是父组件传递给当前组件的新的props,但是父组件的render方法并不能保证传给子组件的props发生变化,也就是说nextProps可能和当前props的值相等,所以需要比较props是否变化再setState,否则可能会发生多次调用。 - shouldComponentUpdate(nextProps,nextState):该方法决定组件是否继续执行更新过程,返回布尔值。一但返回false,后续方法都不再执行,组件但更新过程终止。一般通过比较nextProps,nextState和当前props,state决定方法的返回值。该方法可以用来减少组件不必要的渲染,从而优化组件的性能。
不能调用setState
,否则会引起循环调用问题,render永远无法调用,组件也无法正常渲染。在使用forceUpdate时不被调用。
- componentWillUpdate(nextProps,nextState):该方法在组件render之前调用,可以做为组件更新前执行某些工作的地方,很少用到且新版react已经弃用。
不能调用setState
,否则会引起循环调用问题,render永远无法调用,组件也无法正常渲染。这个方法可以被componentDidUpdate()替代。在使用forceUpdate的时候可以调用。
- componentDidUpdate(prevProps,prevState):组件更新后被调用,可以做为操作更新后DOM的地方,
可以调用setState。
Unmounting — 组件卸载时
- componentWillUnmount():该方法在组件卸载之前调用,可以在这里执行一些清理工作,如清楚组件中的定时器,取消某些网络请求,清除componentDidUpdate手动创建的DOM元素等,以避免引起内存泄露。
生命周期和setState关系图
父子组件调用
- mountComponent负责管理生命周期中的mounting阶段的方法调用
- mountComponent本质上是通过递归渲染内容的,由于递归的特性,
父组件的componentWillMount在其子组件的componentWillMount之前调用,而父组件的componentDidMount在其子组件的componentDidMount之后调用
- updateComponent负责管理生命周期中的updating阶段的方法调用
- updateComponent本质上是通过递归渲染内容的,由于递归的特性,
父组件的componentWillUpdate在其子组件的componentWillUpdate之前调用,而父组件的componentDidUpdate在其子组件的componentDidUpdate之后调用