React的生命周期:
construtor
(1)完成组件的初始化,用来定义当前组件所需要的一些状态,这些状态定义在this.state中; (2)当前生命周期函中必须书写super,否则this的指向会发生错误而报错; (3)在当前生命周期中是访问不到props属性的,如果要访问必须在super以及construtor中添加参数props;
componentWillMount(在17.0中已经废除掉了):
挂载前: (1)在服务端渲染时,可以进行前后端数据的请求; (2)可以在数据第一次被渲染的时候做数据的修改; (3)在当前生命周期中尽量不要使用this.setState,因为当前生命周期函数执行完毕后,会自动执行render函数; (4)可以将外部的数据转换为内部的数据;
render:
渲染时: (1)当前生命周期用来进行数据与视图的结合; (2)render函数第一次执行的时候会将渲染的数据在内存中保存一份(缓存),当第二次数据发生改变后,会将这次新的虚拟DOM与缓存中的虚拟DOM进行对比即Diff算法; (3)只要this.state/this.props发生了改变,那么render函数就会执行;
componentDidMount
挂载后: (1)当前生命周期可以做前后端数据的交互(常用来向后端发送请求数据); (2)可以在当前生命周期获取到真实的DOM,通过this.refs来获取当前DOM元素;
//挂载真实DOM的方法:
ref='h2' 获取DOM元素 this.refs.h2
ref={(el) => { this.dom = el }}
(3)一般情况下在当前生命周期中做一些插件的实例化,如new Swiper();
componentWillReceiveProps(newProps) (在17.0中已经废除掉了)
(1)当this.props发生改变的时候就会执行当前函数; (2)当前函数中会有一个参数,这个参数是一个新的props; (3)在当前生命周期函数中可以对新的props进行修改;
shouldComponentUpdate(newProps,newState)
(1)当this.state/this.props被修改的时候会执行当前生命周期函数; (2)当前生命周期函数执行时必须返回一个true或false值,该值决定了render函数是否执行,若返回值为true则render函数执行,否则render函数不会执行; (3)如果返回值为true则下面的生命周期函数会执行,否则下面的生命周期函数均不会执行; (4)当前生命周期函数中有两个参数,一个是新的props,一个是新的state; (5)当前生命周期特别重要,因为可以做React的性能优化(根据比较新旧state/props进行对比来决定是否需要执行渲染); (6)当前生命周期决定的是render函数是否执行,而不是数据是否修改;
componentWillUpdate(newProps,newState) (在17.0中已经废除掉了)
更新前: (1)在当前生命周期中可以对更新的数据做最后的修改; (2)当前生命周期函数中有两个参数,一个是新的props,一个是新的state
componentDidUpdate
更新后: (1)当前生命周期中可以获取到数据更新后最新的DOM结构; (2)注意当前生命周期会执行多次,所以当需要做业务逻辑操作时一定要判断;
componentWillUnmount
卸载: (1)事件的解绑;(2)数据的移除等操作 总结: 在初次渲染时执行的生命周期函数有: construtor -> componentWillMount -> render -> componentDidMount 当this.props/this.state发生改变的时候执行的生命周期函数: this.props发生改变:componentWillReceiveProps -> ShouldComponentUpdate -> ComponentWillUpdate -> render -> ComponentDidUpdate this.state发生改变:ShouldComponentUpdate -> ComponentWillUpdate -> render -> ComponentDidUpdate React中哪些生命周期函数会执行一次,哪些会执行多次 多次:componentWillReceiveProps;shouldComponentUpdate;ComponentWillUpdate;render;ComponentDidUpdate 一次:construtor;componentWillMount;componentDidMount;componentWillUnmount 在17.0版本中废除的生命周期函数有componentWillMount,componentWillReceiveProps,componentWillUpdate,与此同时增加的生命周期函数有:
getDerivedStateFromProps(nextProps,preState)
(1)根据传入的props来更新state; (2)该方法是一个static(静态)方法,意味着该方法属于React.Component类的方法,所以方法内是无法使用this的,也就意味着无法使用this.setState来更新state,所以该方法是通过直接返回对象的形式来更新state,如果某些props的情况下不需要更新state,直接返回null即可。实际上这个方法和componentDidUpdate搭配使用,就能覆盖componentWillReceiveProps的所有使用场景了。
static getDerivedStateFromProps(nextProps,prevState) {
if(nextProps.pos !== prevState.pos) {
return {
pos:nextProps.pos
}
}
return null;
}
getSnapshotBeforeUpdate
(1)在更新之前获取组件的快照,在组件更新前触发; (2)它的返回值会作为第三个参数传递给后面的componentDidUpdate参数中,和componentDidUpdate一起使用,就能覆盖掉componentWillUpdate的所有使用场景了。
class ScrollingList extends React.Component {
listRef = null;
getSnapshotBeforeUpdate(prevProps,prevState) {
if(prevProps.list.length < this.props.list.length) {
return {
this.listRef.scrollHeight - this.listRef.scrollTop
}
}
return null;
}
componentDidUpdate(prevProps,prevState,snapshot) {
if(snapshot !== null) {
this.listRef.scrollTop = this.listRef.scrollHeight - snapshot;
}
}
render() {
return (
<div ref = {this.setListRef}> </div>
);
}
setListRef = ref => {
this.listRef = ref;
}
}
componentDidCatch(error, info)
如果一个组件定义了componentDidCatch生命周期,它将成为一个错误边界,错误边界会捕捉在渲染期间、在生命周期方法中和在构造函数中的错误,就像使用try catch,不会将错误直接抛出了,保证了应用的可用性。
class A extends React.Component {
constructor() {} // 用于初始化 state
// 用于替换'componentWillReceiveProps',该函数会在初始化和'update'时被调用
// 因为该函数是静态方法,所以在外部无法取得'this'
// 如果需要对比'prevProps',需要单独在'state'中维护
static getDerivedStateFromProps(nextProps,prevState){}
// 判断是否需要更新组件,多用于组件的性能优化
shouldComponentUpdate(nextProps,nextState) {}
// 组件挂载后调用,可以在该函数中进行请求或订阅
componentDidMount() {}
// 用于获取最新的DOM数据
getSnapshotBeforeUpdate() {}
// 组件即将销毁,可以此处移除事件绑定,定时器或销毁数据
componentWillUnMount() {}
// 组件销毁后调用
componentDidUnMount() {}
// 组件更新后调用
componentDidUpdate() {}
// 渲染组件
render()
}