生命周期有哪些以及用法
首次实例化
- getDefaultProps
作用于组件类,只调用一次,返回对象用于设置默认的props,对于引用值,会在实例中共享 - getInitialState
作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props。 - componentWillMount
在完成首次渲染之前调用,此时仍可以修改组件的state。 - reader
必选的方法,创建虚拟DOM,该方法具有特殊的规则:
只能通过this.props和this.state访问数据
可以返回null、false或任何React组件
只能出现一个顶级组件(不能返回数组)
不能改变组件的状态 - componentDidMount
真实的DOM被渲染出来后调用,在该方法中可通过this.getDOMNode()访问到真实的DOM元素。此时已可 以使用其他类库来操作这个DOM。
在服务端中,该方法不会被调用。
实例化之后完成的更新
- getInitialState
- componentWillMount
- render
- componentDidMount
组件已存在时的状态改变
- componentWillReciveProps
组件接收到新的props时调用,并将其作为参数nextProps使用,此时可以更改组件props及state。 - shouldComponentUpdate
组件是否应当渲染新的props或state,返回false表示跳过后续的生命周期方法,通常不需要使用以避免出现bug。在出现应用的瓶颈时,可通过该方法进行适当的优化。
在首次渲染期间或者调用了forceUpdate方法后,该方法不会被调用 - componentWillUpdate
接收到新的props或者state后,进行渲染之前调用,此时不允许更新props或state。 - render
- componentDidUpdate
完成渲染新的props或者state后调用,此时可以访问到新的DOM元素。
组件销毁
- componentWillUnmount
生命周期函数的渊源
自定义组件(ReactCompositeComponent)的生命周期主要通过三种状态进行管理:MOUNTING、RECEIVE_PROPS、UNMOUNTING,它们负责通知组件当前所处的状态,应该执行生命周期中的哪个步骤,是否可以更新 state。三个状态对应三种方法,分别为:mountComponent、updateComponent、unmountComponent,每个方法都提供了两种处理方法
getDefaultProps
这个生命周期函数是在组件初始化构造函数中执行,所以只执行一次
// 构造函数 var Constructor = function(props, context) { this.props = props; this.context = context; this.state = null; var initialState = this.getInitialState ? this.getInitialState() : null; this.state = initialState; };
状态一:MountComponent
由于react构建的是虚拟DOM所以要准备开始渲染页面之前拿到的虚拟的DOM,需要经过组装之后然后给到浏览器,在这里会发生:首先会通过getInitialState拿到初始化的数据
// 当前状态为 MOUNTING this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING; // 当前元素对应的上下文 this.context = this._processContext(this._currentElement._context); // 当前元素对应的 props this.props = this._processProps(this.props); // 获取初始化 state this.state = this.getInitialState();
然后判断如果有componentwillMount就会运行这里的js语法,在这里如果有state发生变化不会马上出发render而是与initialState进行,组成新的state;这里渲染的时候是通过递归的方式进行渲染所以父组件的componentWillMount在子组件的componentWillMount之前执行,而子组件的componentDidMount在父组件的componentDidMount之前执行,这块可能有点绕,直接上代码
// render 递归渲染 var markup = this._renderedComponent.mountComponent( rootID, transaction, mountDepth + 1 );
- 这样就把dom与state以及props数据拿到就可以完整的进行渲染
- 最后判断是否有componentDidMount,如果有会执行这里的js
状态二:receive Props
updateComponent 负责管理生命周期中的 componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render 和 componentDidUpdate。
- compnentWillReciveProps中setState在componentWillReceiveProps、shouldComponentUpdate 和 componentWillUpdate 中还是无法获取到更新后的 this.state,即此时访问的this.state 仍然是未更新的数据,只有在 render 和 componentDidUpdate 中才能获取到更新后的this.state。
- 禁止在 shouldComponentUpdate 和 componentWillUpdate 中调用 setState,会造成循环调用,直至耗光浏览器内存后崩溃。(如果在 shouldComponentUpdate 或 componentWillUpdate 中调用 setState,此时的状态已经从 RECEIVING_PROPS -> NULL,则 performUpdateIfNecessary 就会调用 updateComponent 进行组件更新,但 updateComponent 又会调用 shouldComponentUpdate 和 componentWillUpdate,因此造成循环调用,使得浏览器内存占满后崩溃。)
状态三:unMountComponent
- 在 componentWillUnmount 中调用 setState,是不会触发 reRender。