您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    React要更新,就像渣男会变心
    时间:2021-08-07 12:10 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    React要更新,就像渣男会变心

    大家好,我是卡颂。

    明天和同事聊天,我说他是个铁憨憨,不会和女生聊天。

    他啪的一下跳起来,“我可懂情调了”

    “哦?那你来句土味情话。”

    他清清嗓子,压低了声调,望向远方,渐渐道:

    假设我是component,我对你的情愫在didMount时燃起,直到我生命unmount时熄灭

    合理他沉浸在YY的世界无法自拔时,我说:

    你知道在React18,componentDidMount和componentWillUnmount能够调用屡次么?

    从Strict Mode谈起

    React有个特性 — Strict Mode,被StrictMode包裹的组件在DEV环境会对不引荐写法有更严厉的提示与辅佐检测行为。

    <StrictMode> 

      <div> 

        <ComponentOne /> 

        <ComponentTwo /> 

      </div> 

    </StrictMode> 

    「辅佐检测行为」是指部分办法会被React重复调用,协助开发者更容易发现不标准运用这些办法时的潜在bug。

    一切会被重复调用的API见StrictMode文档[1]

    举个例子:

    function App() { 

      const [num, update] = useState(0); 

     

      function onClick() { 

        update(num + 1); 

      } 

     

      console.log('render'); 

     

      return ( 

        <p onClick={onClick}>{num}</p> 

      ); 

    当App被StrictMode包裹,点击p触发更新后,App组件会render两次。

    在v17之前,例子中console.log会执行两次。但在v17之后,React覆写了console办法,所以console.log只会执行一次,但组件实践会render两次

    这么做的目的是:作为函数组件,App的「反作用」应该在useEffect回调中执行。

    假设不标准书写反作用(比如在组件函数体内写反作用),那么重复render更容易暴露能够产生的bug。

    铺垫完背景。接上去,让我们揭露React善变的渣男行径。

    最近刷v18讨论组时突然发现:StrictMode中会添加一条Strict Effect规则。

    React要更新,就像渣男会变心

    Strict Effect

    复杂的说,相似上文讲到的部分API在StrictMode下会重复执行。

    Strict Effect规则会让useEffect、useLayoutEffect在StrictMode下也会重复执行。

    比如:

    function App() { 

      // 或useLayoutEffect 

      useEffect(() => { 

        // 逻辑1 

        return () => // 逻辑2; 

      }, []) 

       

      // ... 

    在以后React中,组件mount时,执行逻辑1。

    而在Strict Effect规则下,mount时的逻辑如下:

    组件mount时,执行逻辑1

    React模拟组件unmount,执行逻辑2

    React模拟组件mount,执行逻辑1

    留意,这里useEffect的依赖项是[],在以往的认知里,依赖项为「空数组」意味着该useEffect逻辑只会在mount时执行一次。

    而在v18的Strict Mode,由于包含了Strict Effect规则,mount时的useEffect逻辑会被重复执行。

    某种水平上讲,这种打破开发者既有认知的Breaking Change,比Concurrent Mode更让人难以接受。

    那么React团队为什么要设计这条规则呢?

    一切为了Offscreen

    Offscreen是一个开发中的API,估量会在某个v18的小版本发布。

    他的功用相似Vue中的keep-alive,用来在组件「失活」时在后台保存组件形状。

    举个Tab切换的例子,在Posts和Archive之间切换Tab:

    React要更新,就像渣男会变心

    当切换到Posts时,Archive属于「失活」形状。

    假设不需求保存形状,则销毁Archive组件。当切换到Archive Tab时,再重新mount Archive。

    当需求保存形状时,只能将Posts与Archive的形状保存在他们的父组件或形状管理(比如Redux)中。

    而有了Offscreen API,在Fiber树(可以了解为虚拟DOM树)层面,可以保存失活的组件结构与形状。

    这个API的运用场景主要包括:

    切换路由时保存之前路由的形状

    预加载将要切换的路由

    如今成绩来了:当Offscreen组件从「失活」变为「活动」,会触发什么生命周期函数呢?

    答案是:componentDidMount以及:

    useEffect(() => { 

       // 触发这个逻辑... 

    }, []) 

    当Offscreen组件从「活动」变为「失活」时,会触发componentWillUnmount与:

    useEffect(() => { 

       // ... 

       return () => { 

         // 触发这个逻辑... 

       } 

    }, []) 

    所以,这些曾经被以为在组件生命周期中只会触发一次的办法,由于Offscreen,在未来能够会屡次触发。

    这也是React提早在StrictMode中加上Strict Effect规则的缘由。

    就像渣男变心前都会有些失常的举动。

    React18是真的应战

    不管是Offscreen还是Concurrent Mode,可以预见随着v18的到来,React会更弱小,相应的学习曲线会更峻峭。

    这既是机遇,也是应战。

    千万别等变化一股脑到眼前时再抱怨:

    你个渣男,现在说好一心一意只会触发一次,如今为了妖艳新特性,背叛我们的诺言。

    到那时React只会拍拍屁股转身,留下不羁的背影:

    (责任编辑:admin)