componentWillReceiveProps、getDerivedStateFromProps、shouldCompoentUpdate

componentWillReceiveProps组件首次加载时不会触发,只有父组件setstate(不管这次setstate有没有改变传入的props的值或者即使子组件没有被传入props)才会触发子组件的该生命周期,子组件自身的setstate不会触发该生命周期。父级通过静态变量等方式只改变传入子元素的props,父级不setstate的话,是不会触发子级的该生命周期的,因为父组件必须通过setstate重新触发父组件的render方法,才能在render中重新触发子组件的重新渲染,进而触发子组件的该生命周期,即使setstate中不重新设置props的值即props没有变或者setstate一个空对象,也是会触发该生命周期的。
getDerivedStateFromProps组件首次加载时会触发,父组件、子组件setstate会触发、父组件传入该组件的props变化时也会触发。该生命周期中的参数prevstate,如果由于子组件自身setstate的话,该prevstate就是setstate中即将要更新的state,如果是由于外界props变化触发的该函数,那么prevstate就是当前组件的state即this.state。
该生命周期return的state才是最终的state,所以说setstate中的state并不一定是最终的state,因为该生命周期中可能会通过prevstate拿到setstate中的state做一些处理,最后再return一个新的state。
getDerivedStateFromProps中return的state对shouldCompoentUpdate来说 是其参数中的nextstate,对componentDidUpdate来说是其内部的this.state。

shouldCompoentUpdate中的nextstate参数,如果getDerivedStateFromProps函数中有对state处理,那么nextstate就是经过getDerivedStateFromProps处理过的state,如果没有经过该函数的处理,那么nextstate就是setstate中的即将更新的state,如果没有setstate,那么就是本地的state。

componentDidUpdate(prevProps, prevState)中的prevState是组件更新之前(可能是setstate或者外部props变化引起的更新)组件的state,并不是getDerivedStateFromProps中renturn的state。而componentDidUpdate中的this.state正是getDerivedStateFromProps中return的state.

所以 当有getDerivedStateFromProps对state中的某个属性做处理时,shouldCompoentUpdate和componentDidUpdate中的判断就不能通过nextstate或者prevState中的该属性来进行判断了,要通过nextProps、prevProps中的该属性来判断了。getDerivedStateFromProps的用法只是在组件内的state会被外界的props改变的时候才会用改生命周期,所以该生命周期中也只能判断外界props的属性与组件内的state中的属性不一致时才触发return {},其余情况都是return null。

react生命周期中只有shouldCompoentUpdate可以在性能优化方面使用,其他生命周期都不能对性能进行优化。

组件自身setstate是不会触发自身的componentWillReceiveProps生命周期,如下链接
https://segmentfault.com/a/1190000008147645

render中一般不要setstate ,链接如下:
https://github.com/arronf2e/blog/issues/108

只有父组件setstate才会触发子组件的重新渲染,继而触发子组件的componentWillReceiveProps生命周期,链接如下
https://www.zhihu.com/question/57485815

当组件内的state的test既要内部控制,又要被外部组件的props控制,那么就要使用getDerivedStateFromProps, 在组件内state内维护一个外界props的test对应的prevTest属性,维护一个组件内部通过setstate控制的test属性,getDerivedStateFromProps内部判断只有nextprops的test与prevstate.prevtest不一样时才return {test:nextprops.test,prevTest: nextprops.test},其他情况全部return null。组件内部的setstate只去控制test属性就行,不需要去控制prevTest。如果test的变化有需要去请求后端接口,那么如果是内部setstate导致的test的变化,那么可以直接在setstate的回调函数中进行后端接口的请求。如果是因为外部props.test的变化导致触发getDerivedStateFromProps进而导致test的更新的话,需要在componentDidUpdate函数中通过prevProps.test与this.props.test的对比判断,只有两者不相等时才进行后端接口的请求。因为getDerivedStateFromProps会导致componentDidUpdate中的参数prevstate不再是我们之前认为的prevstate了而是最新的state了, 所以componentDidUpdate中只能通过prevProps与this.props中的test对比。

在这里插入图片描述在这里插入图片描述
上述源码中可以看到componentWillReceiveProps执行的时候setstate中的state还没有批量更新到组件的workInProgress.memoizedState中,getDerivedStateFromProps执行的时候已经通过processUpdateQueue将setstate中的state已经批量更新到了workInProgress.memoizedState,所以组件内部setstate触发的getDerivedStateFromProps中的prevstate就是setstate中的即将更新的最新的state。

源码https://segmentfault.com/a/1190000020737054

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值