getDerivedStateFromProps
getSnapshotBeforeUpdate
ComponentDidCatch
生命周期有fiber后就不合适了,向下兼容的特性
getDerivedStateFromProps
功能:将传入的props映射到states上,会在每次re-rendering之前调用。
这意味着,即使props没有变化,而父组件的state变化了,导致了re-rendering,这个生命周期函数依然被调用,这会导致很多问题。
实际使用,代替componentwillreceiveprops。新生命函数是静态函数,不同通过this来访问class,应该通过参数提供的nextprops和prevstate来判断,根据新传入的props来映射state
注意,如果传入的props不能影响state,就会返回null,这个返回是必须的,所以尽量写在函数末尾。
多来源不同状态
如果组件既受控于props,又受控于本身的state,当组件多次调用时,为了防止渲染冲突,就一定要返回 return null。 否则会报错
组织好组件
如果组件既需要自己定义的数据,也需要外部接收的数据,该怎么办,
这是需要注意,数据要么用props驱动,要么state驱动。如果实在没有办法解耦,那么引入hack,绑定props到states上。代码如下:
constructor(props) {
super(props);
this.state = {
type: 0,
props,
}
}
static getDerivedStateFromProps(nextProps, prevState) {
const {type, props} = nextProps;
// 这段代码可能看起来非常混乱,这个props可以被当做缓存,仅用作判断
if (type !== props.type) {
return {
type,
props: {
type,
},
};
}
// 否则,对于state不进行任何操作
return null;
}
从这段代码可以看出,react希望把state和props分离。正如redux作者Dan Abramov说的一样(扩展webpack作者tobias),把所有组件分为容器型组件和展示型组件。一个负责state更新,一个负责props渲染。但实际开发很难控制。
异步
以前在props发生变化了,在componentwillreceiveprops中进行异步操作。这种使用没有功能问题,但是有性能问题。
当外部多个属性在很短时间内变化多次,会导致每次willreceiveprop会被调用多次。这时,可能会导致异步阻塞。
而使用getderivedstatefromprops,则在上面的情况只调用一次,优点明显。
如何处理异步。官方推荐在componentdidupdate中根据新的props和state来异步操作。
一个静态的生命周期可以让状态的修改更加规范合理。
初始化组件的时候,我们有时候需要把props的数据添加到states,让组件响应props的变化。
但组件接收的props是只读的,不可变的.当组件接收了新的props组件的初始化行为并不会发生,所以我们想在getderivedstate/willreceiveprops中获取最新的props,并且setstate这个数据。
看起来像willReceiveProps的替代品,但是在触发机制,参数和可访问数据,具有很大的差异
优雅的做法
React 官方博客中提供了以下几种方案:
让表单控件变成完全受控组件, 不论是 onChange 处理函数还是 value 都由父组件控制, 这样用户无需再考虑这个组件 props 的变化和 state 的更新.
也可以全部变成非受控组件
要保守使用derived state,对于异步的更新,所以直接使用 componentDidUpdate 来确保是基于正确的 props 来更新 state 足以。
也许并不需要派生状态。
组件的初始化和更新都会调用这个函数,这对既依赖本身state,又以来外部props,就会比较麻烦。这个函数在特殊时候用,平常用不到了,可以在didmount和didUpdate中处理逻辑。或者用hooks。代码如下:
const app =(props)=>{
const id={props}
const [name,setName]=useState(’’);
useEffect=(()=>{
//你的逻辑
//根据deps的变化,一旦id或者name变化,都会 处理这里的函数
//这样就相当于在didmount 和didupdate分别处理了
},([id,name]))
return
}
附加:整个生命周期过程
counstructor
getderivedstate
didmount
getderivedstate
shouldcomponent
getsnapshot
didupdate
willunmount
A future version of React will block javascript: URLs as a security precaution. 类似 &被禁止