think icon indicating copy to clipboard operation
think copied to clipboard

React组件生命周期

Open bytemofan opened this issue 8 years ago • 1 comments

实例化

实例化可以理解为组件第一次被创建,生成一个实例。会依次执行以下方法:

  1. getDefaultProps()
  2. getInitialState()
  3. componentWillMount()
  4. render()
  5. componentDidMount()

getDefaultProps()

对于每个组件的实例来说,这个方法只会调用一次,用于设置组件的默认props。后续该类的应用都不会被调用。 es5方式:

var App = React.creatClass({
    getDefaultProps: function(){
        return {
            name: 'pomy',
            git: 'dwqs'
        }
    },
    ...
});

es6语法中则是通过以下方式设置:

static defaultProps = {
      propsName: 'propsValue'
}

getInitialState()

对于每个组件实例来说,这个方法调用有且只有一次,用来初始化每个组件实例的state。每个组件实例都会调用,且只调用一次。 es5

var LikeButton = React.createClass({
  getInitialState: function() {
    return {liked: false};
  },
 ...
});

es6

class App extends React.Component{
       constructor(props){
              super(props);
              this.state = {
                     enable: false
              }
       }
}

修改state使用setState方法,会依次调用下列方法

  1. shouldComponentUpdate
  2. componentWillUpdate
  3. render
  4. componentDidUpdate

componentWIllMount

该方法在首次渲染之前调用,也是在初始化是render调用之前修改state的最后一次机会。

render

该方法用于创建虚拟DOM,用来表示组件的输出。render方法是组件必需的方法,使用时需注意:

  1. 只能通过this.propsthis.state来访问数据(只读数据)
  2. 可以返回null,false或者任何React组件
  3. 只能有一个顶级组件,不能返回一组元素,一组元素必须要有一个容器元素包裹
  4. 不能改变组件的状态(不能调用setState方法)
  5. 不能修改DOM的输出

componentDidMount

该方法在使用服务端渲染方式输出DOM的时候,不会调用。

该方法调用时,已经把虚拟DOM挂载到真实DOM环境中了,可以通过this.getDOMNode()访问到真实的DOM(推荐使用ReactDOM.findDOMNode())。一般我们使用Ajax异步更新DOM时,都是在此方法中实现。

存在期

此时组件以及渲染好,并且用户可以通过交互(如鼠标点击,手指点按等)或事件,导致组件的状态改变。组件的状态改变又分为state改变导致的改变和props改变导致的改变: 因state改变引发的update过程:

  1. shouldComponentUpdate
  2. componentWillUpdate
  3. render
  4. componentDidUpdate

因父组件想要render这个组件改变引发的update过程:

  1. componentWillReciveProps
  2. shouldComponentUpdate
  3. componentWIllUpdate
  4. render
  5. componentDidUpdate

componentWillReciveProps(nextProps)

组件的props值可以由父组件来更改(props是父组件的某一个state且该state发生变化时即更改),props变化时调用componentWillReciveProps方法,可以在该方法中修改state,触发render:

componentWillReceiveProps(nextProps){
    if(nextProps.checked !== undefined){
        this.setState({
            checked: nextProps.checked
        })
    }
}

shouldComponentUpdate(nextProps, nextState)

如果你确定组件的props或者state的改变不需要重新渲染,可以通过在这个方法里返回false来阻止组件重新渲染,且阻止update流程,默认返回的是true:

shouldComponentUpdate: function(nextProps, nextState){
    return this.state.checked === nextState.checked;
}

可以利用该方法实现一些优化,避免过多的组件重新渲染。

componentWillUpdate(nextProps, nextState)

在组件接收到了新的props或者state改变即将进行重新渲染前调用。该方法里不能更新props和state,否则会导致死循环,使应用崩溃。两个参数分别是即将变化的props和state。

componentDidUpdate(prevProps, prevState)

在组件重新被渲染之后调用,类似componentDidMount,可以在该方法中访问和修改DOM。

组件卸载

每当React使用完一个组件,这个组件必须从 DOM 中卸载后被销毁,此时componentWillUnmout 会被执行,完成所有的清理和销毁工作,在 componentDidMount 中添加的任务都需要再该方法中撤销,如创建的定时器或事件监听器。

bytemofan avatar Feb 13 '17 13:02 bytemofan

各生命周期流程图: image

bytemofan avatar Sep 07 '17 06:09 bytemofan