二、React组件的生命周期

3. 组件生命周期

  • React严格定义了组件的生命周期,生命周期可能会经历以下三个过程:浏览器

    • 装载过程(Mount):也就是把组件第一次在DOM树上渲染的过程;
    • 更新过程(Updata):当组件被重新渲染的过程;
    • 卸载过程(Unmount):组件从DOM树中删除的过程。
  1. 三种不一样的过程,React库会调用组件的一些成员函数,即生命周期函数。

3.一、装载过程

  • 当组件第一次被渲染时,依次调用的函数:服务器

    • static propTypes(createClass建立的话:propTypes)
    • static defaultProps(createClass建立的话:getDefaultProps(){})
    • constructor(初始化state;createClass建立的话:getInitalState)
    • componentWillMount
    • render
    • componentDidMount
  1. constructor函数

    ES6中每一个类的构造函数,要建立一个组件类的实例,便会调用对应的构造函数
    注意:this

    1. 并非每一个组件都须要定义本身的构造函数,无状态的React组件每每就不须要定义构造
      函数;
    2. 一个React组件须要构造函数目的:
    • 初始化state,由于组件的生命周期中任何函数均可能要访问state,那么整个周期中第一个被调用的构造函数即是初始化state最理想的地方;
    • 绑定成员函数的this环境:

      - 由于在ES6语法下,类的每一个成员函数在执行时的this并非和类实例自动绑定的;
      - 而在构造函数中this就是当前组件实例,因此,为了方便未来调用,每每在构造函数中将这个实例的特定函数绑定this为当前类实例:code

    ...
       constructor(props){
          super(props);
          
          this.onClickFunc = this.onClickFunc.bind(this);
       }
  2. getInitialState和getDefaultProps
      1. getInitialState函数的返回值用来初始化组件的this.state;
      2. getInitialState只出如今装载过程,也就是说一个组件的整个生命周期过程当中,这个函数只被调用一次;
      3. getDefaultProps函数的返回值能够做为props的初始值;
      4. 两个函数都只有在使用React.createClass方法建立组件类时才会用到component

    const Sample = React.createClass({
       getInitialState: function() {
           return {foo: '返回值将做为this.state的初始值'};
       },
       getDefaultProps: function() {
           return {sampleProp: '做为props的初始值'}
       }
     })

     5. React.createClass建立方法已经逐渐被Facebook官方废弃
      6. 使用ES6时,在构造函数中经过this.state赋值完成状态初始化;经过给类属性(注意是类属性,而不是类的实例对象的属性)defaultProps赋值指定的props初始值:对象

    class Sample extends React.Component{
      constructor (props){
        super(props);
           this.state = {foo: '初始值'}
      }
    }
       Sample.defaultProps = {
      sampleProps: 0
    }
  3. render生命周期

    • render函数是React组件中最重要的函数,一个React组件能够忽略其余全部函数都不实现,但必定要实现render函数,由于全部React组件的父类React.Component类对除了render以外的生命周期函数都有默认实现。
    • 一般一个组件要发挥做用,老是要渲染一些东西,render函数并不作实际的渲染动做,它只是返回一个JSX描述结构,最终由React来操做渲染过程;
    • 当某个特殊的组件做用不是渲染界面,或者没有东西可画时,可以让render函数返回null或者false,即告诉React此组件不渲染任何DOM元素;
    • 注意:render函数应该是一个纯函数,彻底根据this.state和this.props来决定返回的结果,并且不要产生任何反作用,不要在render函数中调用this.setState去改变状态,由于一个纯函数不该该引发状态的改变。
  4. componentWillMount和componentDidMount字符串

    • 在装载过程当中,componentWillMount会在render函数以前调用,此时尚未任何东西渲染出来,即便调用this.setState修改状态也不会发生从新绘制;
    • componentDidMount在render函数以后调用,但render调用以后并不会当即调用,而是在render函数返回的东西已经引起了渲染,组件已经被‘装载’到了DOM树上后,componentDidMount才被调用,此时已绘制出真实的DOM树;
    • 注意:
    1. render函数自己并不往DOM树上渲染或者装载内容,它只是返回一个表示JSX表示的对象(及组件实例),而后由React库根据返回的对象决定如何渲染;
    2. 而React库确定是要把全部组件返回的结果综合起来,才能知道如何产生对应的DOM修改;
    3. 因此只有React库调用全部组件的render函数以后,才有可能完成DOM装载,这时候才会依调用componentDidMount函数做为装载的收尾。
    4. componentWillMount能够在服务器和浏览器端被调用,而componentDidMount只能在浏览器端被调用(由于componentDidMount是在‘装载’完成以后被调用,且‘装载’是一个建立组件并放到DOM树上的过程,而服务器端渲染经过React组件产生的只是一个纯粹的字符串,并不会产生DOM树,即在服务器端不可能完成‘装载过程’因此没法调用componentDidMount)

3.二、更新过程

  • 随着用户的操做改变展现的内容,当props或者state被修改时,就会引起组件的更新过程;
  • 更新过程会依次调用如下生命周期函数,其中render函数和“装载”过程同样:
     - componentWillReceiveProps
     - shouldComponentUpdateget

    • componentWillUpdate
    • render
    • componentDidUpdate
  • 并非全部的更新过程都会执行所有函数。
  1. componentWillReceiveProps(nextProps)

    • 并非只有在组件的props发生改变的时候才会调用此函数;
    • 在更新过程,只要是父组件的render函数被调用,在render函数里被渲染的子组件就会经历更新过程,无论父组件传给子组件的props有没有改变,都会触发子组件的componentWillReceiveProps函数;
    • 注意:经过this.setState方法触发的更新过程不会调用这个函数;
    • 由于,这个函数适合根据新的props值(也就是参数nextProps)来计算是否是要更新内部状态state;而更新内部状态的方法是this.setState,若是this.setState的调用致使componentWillReceiveProps再调用,那将是一个死循环。
  2. shouldComponentUpdate(nextProps,nextState)

    • 除了render函数,shouleComponentUpdate多是生命周期函数中最重要的一个函数;
    • 由于render函数决定了该渲染什么,shouldComponentUpdate决定了一个组件何时不须要渲染;
    • render和shouldComponentUpdate也是React生命周期函数中惟二两个要求有返回结果的函数;
    • render函数的返回结果用于构建DOM对象,shouldComponentUpdate函数返回一个布尔值,告诉React库这个组件此次更新过程是否继续;
    • 在更新过程当中,React库首先调用shouldComponentUpdate函数,若是这个函数返回true,那就继续更新过程,接下来调用render,反之则终止这次更新过程;
    • shouldComponentUpdate的参数就是接下来的props和state值;咱们能够根据这两个参数,外加this.props和this.state来判断返回true或false,从而避免没必要要的更新。
  3. componentWillUpdate和componentDidUpdate

    • 若是组件的shouldComponentUpdate返回true,React接下来调用componentWillUpdate、render和componentDidUpdate;
    • 和“装载”过程不一样,这对函数均可以在服务器和浏览器更新阶段调用
    • 不过,一般在使用React作服务端渲染时,基本不会经历更新过程,由于服务器端只须要产出HTML字符串,而一个装载过程就足够产出HTML字符串了,因此正常状况下,服务器端不会调用componentDidUpdate函数,若是调用了,说明程序有错,须要改进。

3.二、卸载过程

  • React组件的卸载过程只涉及一个函数componentWillUnmount,
  • 当React组件要从DOM树上删除以前,对应的componentWillUnmount函数会被调用,因此这个函数适合作一些清理性的工做。
相关文章
相关标签/搜索