你的浏览器不支持canvas

Enjoy life!

React - lifecycle

Date: Author: JM

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

一、lifecycle - 生命周期

  • 生命周期泛指自然界和人类社会中各类客观事物的阶段性变化及规律。
  • 生命周期是单一方向不可逆的过程,但是软件开发的生命周期却会根据方法的不同,在完成前重新开始
  • React 组件的生命周期根据广义定义描述,可以分为挂载、渲染和卸载。
  • 当渲染后的组件需要更新时,我们会重新去渲染组件,直至卸载。
  • 因此,我们可以把 React 生命周期分成两类:
    • 当组件在挂载或卸载时;
    • 当组件接收新的数据时,即组件更新时

relationship-map

二、挂载阶段

2.1 介绍

  • 组件的挂载是最基本的过程,这个过程主要做组件状态的初始化
import React, { Component, PropTypes } from 'react';
class App extends Component {
 static propTypes = {
 // ...
 };
 static defaultProps = {
 // ...
 };
 constructor(props) {
 super(props);
 this.state = {
 // ...
 };
 }
 componentWillMount() {
 // ...
 } 
  componentDidMount() {
  // ...
  }
  render() {
  return <div>This is a demo.</div>;
  }
 } 
  • 挂载顺序顺序如下
    • constructor ===》 componentWillMount ===》 render ===》 componentDidMount

2.2 getDefaultProps()

  • 设置默认的props,也可以用defaultProps设置组件的默认属性。

2.3 constructor()

  • getInitialState() ==》 constructor
    • 在使用es6class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state
    • 此时可以访问this.props

2.4 componentWillMount

  • componentWillMount()
    • 在首次完成渲染之前调用,基本业务逻辑都应该放到这里。
    • 整个生命周期只调用一次。
    • 是在首次渲染之前修改state的最后一次机会。

2.5 render

  • render()
    • react最重要的步骤,创建虚拟dom,使用diff算法,更新dom
    • 只能通过this.propsthis.state访问数据;
    • 可以返回nullfalse或任何React组件。
    • 只能出现一个顶级组件(不能返回数组)。
    • 不能改变组件的状态。
    • 不能修改DOM的输出。

2.6 componentDidMount

  • componentDidMount()
    • 组件渲染之后调用,可以通过this.getDOMNode()获取和操作dom节点,只调用一次。
    • 一般情况下网络请求(AJAX) 可以放到DOM渲染完成之后,即:放到这个方法中执行。

三、卸载阶段

import React, { Component, PropTypes } from 'react';
class App extends Component {
 componentWillUnmount() {
 // ...
 }
 render() {
 return <div>This is a demo.</div>;
 }
} 
  • componentWillUnmount()
    • 组件将要卸载时调用,一些事件监听和定时器需要在此时清除。

四、更新阶段

4.1 介绍

  • 更新过程是指:父组件向下传递 props 或者组件自身执行 setState 方法时发生的一系列更新的动作。
import React, { Component, PropTypes } from 'react';
class App extends Component {
 componentWillReceiveProps(nextProps) {
 // this.setState({})
 }
 shouldComponentUpdate(nextProps, nextState) {
 // return true;
 }
 componentWillUpdate(nextProps, nextState) {
 // ...
 }
 componentDidUpdate(prevProps, prevState) {
 // ...
 }
 render() {
 return <div>This is a demo.</div>;
 }
} 
  • 组件自身的 state 更新
    • 依次执行:shouldComponentUpdate ===》 componentWillUpdate ===》 render ===》 componentDidUpdate

4.3 shouldComponentUpdate(props, state)

  • shouldComponentUpdate 是一个特别的方法:
    • 它接收需要更新的 propsstate,让开发者增加必要的条件判断,让其在需要时更新,不需要时不更新。
      • 我们可以设置在此对比前后两个propsstate是否相同,如果相同则返回false阻止更新。【默认情况,返回true,在state或者props改变的时候调用】
      • 因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候。
    • 因此,当方法返回 false 的时候,组件不再向下执行生命周期方法。
    • 该方法在初始化渲染的时候不会调用,在使用 forceUpdate 方法的时候也不会。
  • 默认情况下,React 会渲染所有的节点,因为 shouldComponentUpdate 默认返回 true
  • 正确的组件渲染从另一个意义上说,也是性能优化的手段之一。
  • shouldComponentUpdate 的本质是 用来进行正确的组件渲染

lifecycle

  • 如上图所示:当父节点 props 改变的时候,在理想情况下,只需渲染在一条链路上有相关 props 改变的节点即可。

4.4 componentWillReceivePorps

  • componentWillReceivePorps(nextProps)
    • props是从父组件传过来的,是动态的可以修改的。
    • 组件初始化时不调用,组件接受新的props时调用。
    • 这里修改的state也不会引起render的重复渲染。

4.5 componentWillUpdate

  • componentWillUpdate(nextProps, nextState)
    • 组件初始化时不调用,只有在组件将要更新时才调用。
    • 在接收到新的props或者是state的时以及在render之前调用。
    • 在该方法中不再允许更新propsstate,如果你需要更新props或者state,可以在componentWillReceiveProps中修改。

4.6 componentDidUpdate

  • componentDidUpdate()
    • 组件初始化时不调用,组件更新完成后调用,即:完成渲染新的props或者state后调用。
    • 此时可以获取dom节点。

五、总结

relationship-map


对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。