一、组件的三种状态
状态一:MOUNTING(正在加载)
mountComponent 负责管理生命周期中的 getInitialState、componentWillMount、render 和 componentDidMount。
1、Constructor(构造函数) 管理 getDefaultProps;
2、首先通过 mountComponent 装载组件;
3、将状态设置为 MOUNTING;
4、(1)执行 getInitialState 获取初始化 state,初始化更新队列;
5、(2)执行 componentWillMount,【【【在它内部调用 setState,不会触发 reRender,而是进行 state 合并】】】;
6、更新状态为 NULL【标注1】,更新state【标注2】 ;
7、(3)执行 render,在它内部可以获取更新后的 this.state 数据;
8、(4)执行 componentDidMount。
状态二:RECEIVE_PROPS(收到属性)
updateComponent 负责管理生命周期中的 componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render 和 componentDidUpdate。updateComponent 本质上也是通过 递归渲染 内容的,由于递归的特性,父组件的 componentWillUpdate 一定在其子组件的 componentWillUpdate 之前调用,而父组件的 componentDidUpdate 肯定在其子组件 componentDidUpdate 之后调用。
1、将状态设置为 RECEIVING_PROPS;
2、执行(1)componentWillReceiveProps,【【【在它内部调用setState,不会触发 reRender,会进行 state 合并】】】;
3、更新状态为 NULL【标注1】;
4、执行(2)shouldComponentUpdate判断是否需要进行组件更新;
5、执行(3)componentWillUpdate;
6、更新state【标注2】;
7、执行(4)render;
8、执行(5)componentDidUpdate;
状态三:UNMOUNTING(正在卸载)
unmountComponent 负责管理生命周期中的 componentWillUnmount。
1、将状态设置为 UNMOUNTING;
2、执行componentWillUnmount,在它的内部调用 setState,不会触发 reRender。
3、更新状态为 NULL【标注1】,完成组件卸载操作。
二、setState循环调用
1、调用 setState 时,如果当前状态不是 NULL,那么会进行state合并;如果当前状态是 NULL,那么会调用enqueueUpdate(列队更新) 执行更新,进而调用 updateComponent(更新组件), 进而调用 shouldComponentUpdate 和 componentWillUpdate。
2、如果在 shouldComponentUpdate 或 componentWillUpdate 中调用 setState,因为此时的状态是 NULL,所以就会调用 enqueueUpdate(列队更新) 执行更新,进而调用 updateComponent(更新组件), 进而调用 shouldComponentUpdate 和 componentWillUpdate,造成循环调用。
3、在render及它后面的生命周期里调用setstate,毫无疑问也会造成循环调用。
4、isBatchingUpdates默认是false,表示setState会同步更新this.state;另,对 NULL 进行布尔转换,也是false。