React组件生命周期

React组件的生命周期有一堆的相关函数,其实就是一推的钩子函数。在React组件建立的各个阶段触发特定的钩子函数。react

能够先大概看一下下面这张图:
图片描述安全

constructor

构造函数,在建立组件的时候调用一次。服务器

constructor(props, context)

componentWillMount

在组件挂载以前调用一次。若是在这个函数里面调用setState,render()知道state发生变化,而且只渲染一次。网络

void componentWillMount()

render

render是一个React组件所必不可少的核心函数。不要在render里面修改state。也不要去读写DOM或者与服务器交互,保持render()方法的纯净。app

ReactElement render()

componentDidMount

在组件挂载以后调用一次。这个时候,子组件也都挂载好了,能够在这里使用refs。dom

void componentDidMount()

shouldComponentUpdate

这个方法在初始化render时不会执行,当props或者state发生变化时执行。函数默认返回true,须要从新render。返回false,就不会从新render了。componentWillUpdate和componentDidUpdate方法也不会被调用。在比较复杂的应用里,有一些数据的改变并不影响界面展现,能够在这里作判断,优化渲染效率。函数

boolean shouldComponentUpdate(
    object nextProps, object nextState
)

componentWillUpdate

shouldComponentUpdate返回true以后,componentWillUpdate会被调用。须要特别注意的是,在这个函数里面,不要用this.setState来修改状态。否则这个函数会无限循环执行。这个函数调用以后,就会把nextProps和nextState分别设置到this.props和this.state中。紧接着这个函数,就会调用render()来更新界面了。测试

void componentWillUpdate(
  object nextProps, object nextState
)

componentDidUpdate

除了首次render以后调用componentDidMount,其它render结束以后都是调用componentDidUpdate。优化

void componentDidUpdate()

componentWillReceiveProps

props是父组件传递给子组件的。父组件发生render的时候子组件就会调用componentWillReceiveProps(无论props有没有更新,也无论父子组件之间有没有数据交换)。在这个回调函数里面,你能够根据属性的变化,经过调用this.setState()来更新你的组件状态,旧的属性仍是能够经过this.props来获取,这里调用更新状态是安全的,并不会触发额外的render调用。ui

void componentWillReceiveProps(nextProps) {
    this.setState({...});
}

componentWillUnmount

当组件要被从界面上移除的时候,就会调用componentWillUnmount(),在这个函数中,能够作一些组件相关的清理工做,例如取消计时器、网络请求等。

void componentWillUnmount()

下面是一个React组件生命周期的测试例子

var React = require('react');
var ReactDOM = require('react-dom');

class Parent extends React.Component {
  constructor(){
    super()
    console.log("%cparent -- constructor","color:green");
    this.state = {
      name : 'Lucy'
    }
  }

  componentWillMount(){
    console.log("%cparent -- componentWillMount","color:green");
  }

  componentDidMount(){
    console.log("%cparent -- componentDidMount","color:green");
  }

  componentWillReceiveProps(){
    console.log("%cparent -- componentWillReceiveProps","color:green");
  }

  shouldComponentUpdate(){
    console.log("%cparent -- shouldComponentUpdate","color:green");
    return true;
  }

  componentWillUpdate(){
    console.log("%cparent -- componentWillUpdate","color:green");
  }

  componentDidUpdate(){
    console.log("%cparent -- componentDidUpdate","color:green");
  }

  componentWillUnmount(){
    console.log("%cparent -- componentWillUnmount","color:green");
  }

  changeName(){
    this.setState({name : 'Jone'})
  }

  unmountComponent(){
    ReactDOM.unmountComponentAtNode(document.getElementById("app"));
  }

  render(){
    console.log("%cparent -- render","color:green");
    return(
      <div style={{border:'1px solid #000',color:'green'}}>
        <h2>Parent:</h2>
        <h3>hello {this.state.name}</h3>
        <button onClick={this.changeName.bind(this)}>state改变</button>
        <button onClick={this.unmountComponent.bind(this)}>卸载组件</button>
        <Child props1="haha"></Child>
      </div>
    )
  }
}


class Child extends React.Component {
  constructor(){
    super()
    console.log("  %cchild -- constructor","color:blue");
    this.state = {
    }
  }

  componentWillMount(){
    console.log("  %cchild -- componentWillMount","color:blue");
  }

  componentDidMount(){
    console.log("  %cchild -- componentDidMount","color:blue");
  }

  componentWillReceiveProps(){
    console.log("  %cchild -- componentWillReceiveProps","color:blue");
  }

  shouldComponentUpdate(){
    console.log("  %cchild -- shouldComponentUpdate","color:blue");
    return true;
  }

  componentWillUpdate(){
    console.log("  %cchild -- componentWillUpdate","color:blue");
  }

  componentDidUpdate(){
    console.log("  %cchild -- componentDidUpdate","color:blue");
  }

  componentWillUnmount(){
    console.log("  %cchild -- componentWillUnmount","color:blue");
  }

  changeName(){
    this.setState({name : 'Jone'})
  }

  render(){
    console.log("  %cchild -- render","color:blue");
    return(
      <div style={{border:'1px solid #000',margin:'10px',color:'blue'}}>
        <h2>Child:</h2>
      </div>
    )
  }
}

ReactDOM.render(
  <Parent></Parent>,
  document.getElementById('app')
);

测试例子截图以下:

图片描述

改变父组件的state:
图片描述

卸载组件后:
图片描述

相关文章
相关标签/搜索