前言
❝React新版生命周期,个人语言描述有问题可以反馈>v<
❞
import React, { Component } from 'react'
export default class LifeCycle extends Component {
//// props = {age:10,name:'计数器'}
static defaultProps = {
name:'计数器'
}
constructor(props){
//Must call super constructor in derived class before accessing 'this' or returning from derived constructor
super();//this.props = props;
this.state = {number:0,users:[]};//初始化默认的状态对象
console.log('1. constructor 初始化 props and state');
}
//componentWillMount在渲染过程中可能会执行多次
componentWillMount(){
console.log('2. componentWillMount 组件将要挂载');
//localStorage.get('userss');
}
//componentDidMount在渲染过程中永远只有执行一次
//一般是在componentDidMount执行副作用,进行异步操作
componentDidMount(){
console.log('4. componentDidMount 组件挂载完成');
fetch('https://api.github.com/users').then(res=>res.json()).then(users=>{
console.log(users);
this.setState({users});
});
}
shouldComponentUpdate(nextProps,nextState){
console.log('Counter',nextProps,nextState);
console.log('5. shouldComponentUpdate 询问组件是否需要更新');
return true;
}
componentWillUpdate(nextProps, nextState){
console.log('6. componentWillUpdate 组件将要更新');
}
componentDidUpdate(prevProps, prevState)){
console.log('7. componentDidUpdate 组件更新完毕');
}
add = ()=>{
this.setState({number:this.state.number});
};
render() {
console.log('3.render渲染,也就是挂载')
return (
<div style={{border:'5px solid red',padding:'5px'}}>
<p>{this.props.name}:{this.state.number}</p>
<button onClick={this.add}>+</button>
<ul>
{
this.state.users.map(user=>(<li>{user.login}</li>))
}
</ul>
{this.state.number%2==0&&<SubCounter number={this.state.number}/>}
</div>
)
}
}
class SubCounter extends Component{
constructor(props){
super(props);
this.state = {number:0};
}
componentWillUnmount(){
console.log('SubCounter componentWillUnmount');
}
//调用此方法的时候会把新的属性对象和新的状态对象传过来
shouldComponentUpdate(nextProps,nextState){
console.log('SubCounter',nextProps,nextState);
if(nextProps.number%3==0){
return true;
}else{
return false;
}
}
//componentWillReceiveProp 组件收到新的属性对象
componentWillReceiveProps(){
console.log('SubCounter 1.componentWillReceiveProps')
}
render(){
console.log('SubCounter 2.render')
return(
<div style={{border:'5px solid green'}}>
<p>{this.props.number}</p>
</div>
)
}
}
React生命周期做了什么以及能做什么?
「初始化 」
defaultProps()、propTypes()
- 查看是否设置了默认属性以及属性校验
constructor (异步请求有特殊情况的话也可以放这里)
- 初始化属性和状态
- react组件的构造函数在挂载之前被调用。 super() 如果类进行了继承的话需要调用这个
- 在这块不能调用setState
getDerivedStateFromProps(props,state)
- 接收传入的props,映射到state
- 将父组件传递过来的 props 映射 到子组件的 state 上面,这样组件内部就不用再通过 this.props.xxx 获取属性值了,统一通过 this.state.xxx 获取。
- state={a:this.props.a} props的a发生变化时 会影响到state触发更新
- 当组件的state需要根据props来改变的时候可调用此方法 这个方法是在 render() 前会被执行,每次触发render前,都会触发此方法。 需要配置 constructor(props){super(props) ,this.state={props}} 才能打印出值
render() 创建虚拟dom进行diff算法
- 创建虚拟dom,进行diff算法,更新dom树都在此进行。 此时就不能更改state了。
- 必须要有返回值,一般为null
componentDidMount() (异步请求放这里)
- 虚拟DOM挂载到页面代替真实DOM
- 组件挂载到DOM后调用,且只会被调用一次
- 组件开始运行 ,state可以被修改, 「 组件更新时」
getDerivedStateFromProps(props,state)
- 接收传入的props,映射到state
- 更新时再次调用该钩子 父组件传递过来的 props 映射 到子组件的 state
shouldComponentUpdate(nextProps, nextState) 新的属性 , 新的状态
- 旧状态和新状态对比判断是否需要更新组件? true of false
- 用当前的this.state/props和nextProps/state新的进行判断 此方法通过比较nextProps,nextState及当前组件的this.props,this.state,返回true时当前组件将继续执行更新过程,返回false则当前组件更新停止,以此可用来减少组件的不必要渲染,优化组件性能。
- 默认返回值 return true false就不会渲染更新视图
render()
- 更新虚拟DOM , 覆盖真实DOM,完成视图渲染
getSnapShotBeforeUpdate(prevProps,prevState) 快照 get(获取) SnapShot(快照)
- 触发时间
- update发生的时候(更新 DOM 和 refs 之前)
- 在render之后,在组件dom渲染之前;
- 接收父组件传递过来的 props 和组件之前的状态,此生命周期钩子必须有返回值,返回值将作为第三个参数传递给componentDidUpdate。必须和 componentDidUpdate 一起使用,否则会报错
- 作用:在组件更新 DOM 和 refs 之前,从 DOM 中捕获一些信息(例如滚动位置)必须有返回值 它能让你,在组件更新 DOM 和 refs 之前,它能让你从 DOM 中捕获一些信息9例如滚动位置)必须有返回值
- 触发时间
componentDidUpdate(prevProps,prevState,snaPshot) 接收快照 根据标识来更新状态
- 组件更新完毕
- 组件更新结束之后执行,在初始化render时不执行
- 避免使用setState,如果componentDidMount 也setState 会进行死循环
「组件卸载」
- componentWillUnmount() ,可以在这里执行一些清理工作
旧版生命周期
❝相比较于新版生命周期,官方去掉了一些可能产生问题的生命周期,且新增了快照能够获取更新钱的状态
❞
新版对比旧版
- 废除componentWillMount(避免bug)
- 新增 : 用getDerivedStateFromProps(props,state) 代替
- 废除componentWillReceiveProps(有bug)
- 废除componentWillUpdate
- 新增:getSnapshotBeforeUpdate
父子之间组件触发顺序
over
本文使用 mdnice 排版