一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
一、旧生命周期的问题
React官网已经在组件API文档中明确说明 UNSAFE_componentWillMount()、 UNSAFE_componentWillUpdate()、 UNSAFE_componentWillReceiveProps()这几个旧生命周期钩子即将过时,开发者们在新代码中应避免使用它们。因为它们确实存在很多问题,容易被误解和滥用。
(1)componentWillMount在SSR中这个方法会被多次调用,会导致重复触发多次,同时若在这个方法内绑定事件将无法解绑,会造成内存泄露,这个方法变得不够安全高效而逐步被放弃。
(2)componentWillReceiveProps外部组件多次频繁更新传入多次不同的props,会导致不必要的异步请求。
(3)componentWillupdate,更新前记录DOM状态,可能会做一些处理,与componentDidUpdate相隔时间如果过长会导致状态不可信。
二、新生命周期的替代
static getDerivedStateFromProps(nextProps, nextState)
getDerivedStateFromProps在第一次的初始化组件以及后续更新的更新过程中(包括自身状态更新以及父传子)会被调用,返回一个对象作为新的state,返回null说明不需要在这里更新state。
[注意] getDerivedStateFromProps是一个静态的类的方法,因此需要加上static关键字
简单来说,getDerivedStateFromProps的执行时机就是在组件初始化的时候以及组件后续更新的时候。同时getDerivedStateFromProps也可以最早的在父传子的时候获取到父组件传递给子组件的属性。由此可见,getDerivedStateFromProps很好的代替了componentWillMount以及componentWillReceiveProps。
static getDerivedStateFromProps(nextProps,nextState){
if(nextProps.value!==undefined){
return {
current:nextProps.value
}
}
return null
}
getSnapshotBeforeUpdate取代了componentWillUpdate,触发时机为update发生的时候,在render之后、dom渲染之前返回一个值,作为componentDidUpdate的第三个参数。
比如列表更新后新的数据不断插入到数据前面,如何保证可视区依旧是之前看到的呢?(详细案例可以查看官网)
getSnapshotBeforeUpdate(){
return this.refs.wrapper.scrollHeight
}
componentDidUpdate(prevProps,prevState,preHeight){
this.refs.wrapper.scrollTop+=this.refs.wrapper.scrollHeight-preHeight
}
.....