组件的生命周期
React严格定义了组件的生命周期,生命周期经历以下三个过程:
·装载过程(Mount),也就是把组件第一次在DOM树中渲染的过程
·更新过程(Update),当组件重新渲染的过程;
·卸载过程(Unmount),组件从DOM中删除的过程;
装载过程( Mount )
组件状态的初始化,包括读取 state 和 props 以及两个组件生命周期方法componentWillMount()、componentDidMout(),这些都只会在组件初始化时运行一次
constructor(): 创造一个组件的实例需要调用,无状态函数(stateless function)不需要定义
· React组件需要构造函数时,往往是为了下面的目的:
· 绑定成员函数的 this 环境
· 初始化 state,因为组件生命周期中任何函数都可能访问 state 所以生命周期中第一个被调用的
构造函数自然是初始化 state最理想的地方
componentWillMount()
此方法会在调用 render() 函数之前被调用,发生在 “将要装载” 的时候,这个时候没有任何渲染出来的结果,即使调用 this.setState() 修改状态也不会引发重新渲染(render函数不会执行), 组件只会渲染一次;但是组件会更新state,完全可以到 constructor()中做初始化。
·render()
·
componentDidMount()
· 组件被挂载到页面之后,自动被执行;并且只在页面初始化的时候执行,之后不会再执行;
render()被调用完之后,componentDidMount()并不会被立刻调用;而是等待所有的子组件里的 render()
执行完成以后,一次调用各个组件的 componentDidMount()以后, 顶层再去调用 componentDidMount()
` 如果在 componentDidMount() 中执行 this.setState() 时, render() 函数会再次调用执行一次,
componentWillMount()和componentDidMount()不会再执行,组件就会在初始化阶段更新两次
· 当componentDidMount() 被调用的时候,render()函数返回的东西已经引发了渲染,组件已经被 "装载"
到了DOM树上 ( 组件已经被解析成 DOM 元素并且已经添加到 HTML 中 )
componentDidMount() 适合页面初始化适合进行 ajax() 请求
axios.get( url )
.then( ( res ) => {
let data = res.data;
this.setState( () => {
data: data
} )
} )
.catch( ( err ) => {
console.log( err );
} );
更新过程( Update )
componentWillReceiveProps( nextProps )
· 一个组件要从父组件接受参数;
· 如果这个组件第一次存在于父组件中,不会执行
· 如果这个组件之前已经存在于父组件中,才会执行
· 父组件的 render() 在被第二次调用时,在 render() 里面被渲染的子组件就会经历更新过程,不管父组件
传给子组件的props有没有改变,都会触发子组件的coomponentWillReveiveRprops()
· 如果组件是由父组件更新 props 而更新的,那么在 shouldComponentUpdate()之前会先执行
componentWillReceiveProps()
· 通过 this.setState() 方法触发的更新过程不会调用这个函数,因为 componentWillReceiveProps()适合
根据新的 props 值(也就是参数 nextProps )来计算出是不是要更新内部状态 state。更新组件内部状态的
方法就是this.setState(),如果this.setState()的调用导致componentWillReceiveProps()再一次被调用,
那就是一个死循环
示例:
constructor( props ){
super( props );
this.state = {
list: [ ...props.list ]
}
}
componentWillReceiveProps( nextProps ){
if( nextProps !== this.props ){
this.setState( ( prevState ) => ({
list: nextProps.list
}))
}
}
shouldComponentUpdate( nextProps, nextState )
1、如果组件更新前(重新渲染前)并且组件自身的 state 更新之后,那么会依次执行shouldComponentUpdate()、componentWillUpdate()、render()、和 componentDidUpdate() 函数
2、如果组件时有父组件更新 props 而更新,那么在 shouldComponentUpdate()之前会执行 componentWillReceiveProps()
3、shouldComponentUpdate() 接收需要更新的 props 和 state, 通过增加必要的条件判断, 让其需要时更新,不需要时不更新。因此当方法返回 true,那就会继续更新过程(调用componentWillUpdate()函数),然后调用 render() 函数;如果返回 false, 就立刻停止更新过程,组件不会重新渲染,组件不在向下执行生命周期方法
例
shouldComponentUpdate( nextProps, nextState ) {
if( nextProps.data ! == this.props.data ) {
return true;
}else{
return false;
}
};
render()
componentWillUpdate( nextProps, nextState )
组件被完成更新之后才会执行
componentDidUpdate()
1、代表着更新过程中渲染后的时刻,此方法需要提供新更新前的 props 和 state
2、componentDidUpdate() 中不能执行 this.setState()此方法不仅可以在浏览器执行还可以在服务器端执行; 一旦在服务器端执行,很可能是程序报错
卸载过程( Unmount )
componentWillUnmount()
1、当这个组件即将被从页面中提出的时候,会被执行
2、在 componentWillUnmount() 中,常常会执行一些清理方法,如事件回收或是清空定时器,componentDidMount() 用非 React 的方法创造了一些 DOM 元素,如果撒手不管可能会造成内存泄露,那就需要在 componentWillUnmount() 清理这些 DOM 元素
React与DOM
React 提供的获取 DOM 元素的方法有两种
findDOMNode():
1)DOMElement findDOMNode( ReactComponent component )
2)如果在 render() 返回 null, 那么 findDOMNode() 返回的也是 null,findDOMNode()只对已挂载的组件有效
3)当组件被渲染到 DOM 中后,findDOMNode() 返回 React 组件实例的相应的 DOM 节点,它可以用于获取表单的 value 以及用于 DOM 的测量
· unmountComponentAtNode()
· render()
生命周期的整体流程: