日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
React要更新,就像渣男會(huì)變心

大家好,我是卡頌。

今天和同事聊天,我說(shuō)他是個(gè)鐵憨憨,不會(huì)和女生聊天。

他啪的一下跳起來(lái),“我可懂情調(diào)了”

“哦?那你來(lái)句土味情話?!?/p>

他清清嗓子,壓低了腔調(diào),望向遠(yuǎn)方,緩緩道:

  • 如果我是component,我對(duì)你的情愫在didMount時(shí)燃起,直到我生命unmount時(shí)熄滅

正當(dāng)他沉浸在YY的世界無(wú)法自拔時(shí),我說(shuō):

  • 你知道在React18,componentDidMount和componentWillUnmount可能調(diào)用多次么?

從Strict Mode談起

React有個(gè)特性 — Strict Mode,被StrictMode包裹的組件在DEV環(huán)境會(huì)對(duì)不推薦寫法有更嚴(yán)格的提示與輔助檢測(cè)行為。

 
 
 
 
  1.  
  2.   
     
  3.      
  4.      
  5.   
 
  •  
  • 「輔助檢測(cè)行為」是指部分方法會(huì)被React重復(fù)調(diào)用,幫助開發(fā)者更容易發(fā)現(xiàn)不規(guī)范使用這些方法時(shí)的潛在bug。

    所有會(huì)被重復(fù)調(diào)用的API見StrictMode文檔[1]

    舉個(gè)例子:

     
     
     
     
    1. function App() { 
    2.   const [num, update] = useState(0); 
    3.  
    4.   function onClick() { 
    5.     update(num + 1); 
    6.   } 
    7.  
    8.   console.log('render'); 
    9.  
    10.   return ( 
    11.     {num}

       
    12.   ); 

    當(dāng)App被StrictMode包裹,點(diǎn)擊p觸發(fā)更新后,App組件會(huì)render兩次。

    • 在v17之前,例子中console.log會(huì)執(zhí)行兩次。但在v17之后,React覆寫了console方法,所以console.log只會(huì)執(zhí)行一次,但組件實(shí)際會(huì)render兩次

    這么做的目的是:作為函數(shù)組件,App的「副作用」應(yīng)該在useEffect回調(diào)中執(zhí)行。

    如果不規(guī)范書寫副作用(比如在組件函數(shù)體內(nèi)寫副作用),那么重復(fù)render更容易暴露可能產(chǎn)生的bug。

    鋪墊完背景。接下來(lái),讓我們揭露React善變的渣男行徑。

    最近刷v18討論組時(shí)突然發(fā)現(xiàn):StrictMode中會(huì)增加一條Strict Effect規(guī)則。

    Strict Effect

    簡(jiǎn)單的說(shuō),類似上文講到的部分API在StrictMode下會(huì)重復(fù)執(zhí)行。

    Strict Effect規(guī)則會(huì)讓useEffect、useLayoutEffect在StrictMode下也會(huì)重復(fù)執(zhí)行。

    比如:

     
     
     
     
    1. function App() { 
    2.   // 或useLayoutEffect 
    3.   useEffect(() => { 
    4.     // 邏輯1 
    5.     return () => // 邏輯2; 
    6.   }, []) 
    7.    
    8.   // ... 

    在當(dāng)前React中,組件mount時(shí),執(zhí)行邏輯1。

    而在Strict Effect規(guī)則下,mount時(shí)的邏輯如下:

    • 組件mount時(shí),執(zhí)行邏輯1
    • React模擬組件unmount,執(zhí)行邏輯2

    • React模擬組件mount,執(zhí)行邏輯1

    注意,這里useEffect的依賴項(xiàng)是[],在以往的認(rèn)知里,依賴項(xiàng)為「空數(shù)組」意味著該useEffect邏輯只會(huì)在mount時(shí)執(zhí)行一次。

    而在v18的Strict Mode,由于包含了Strict Effect規(guī)則,mount時(shí)的useEffect邏輯會(huì)被重復(fù)執(zhí)行。

    某種程度上講,這種打破開發(fā)者既有認(rèn)知的Breaking Change,比Concurrent Mode更讓人難以接受。

    那么React團(tuán)隊(duì)為什么要設(shè)計(jì)這條規(guī)則呢?

    一切為了Offscreen

    Offscreen是一個(gè)開發(fā)中的API,預(yù)計(jì)會(huì)在某個(gè)v18的小版本發(fā)布。

    他的功能類似Vue中的keep-alive,用來(lái)在組件「失活」時(shí)在后臺(tái)保存組件狀態(tài)。

    舉個(gè)Tab切換的例子,在Posts和Archive之間切換Tab:

    當(dāng)切換到Posts時(shí),Archive屬于「失活」?fàn)顟B(tài)。

    如果不需要保存狀態(tài),則銷毀Archive組件。當(dāng)切換到Archive Tab時(shí),再重新mount Archive。

    當(dāng)需要保存狀態(tài)時(shí),只能將Posts與Archive的狀態(tài)保存在他們的父組件或狀態(tài)管理(比如Redux)中。

    而有了Offscreen API,在Fiber樹(可以理解為虛擬DOM樹)層面,可以保存失活的組件結(jié)構(gòu)與狀態(tài)。

    這個(gè)API的應(yīng)用場(chǎng)景主要包括:

    • 切換路由時(shí)保存之前路由的狀態(tài)
    • 預(yù)加載將要切換的路由

    現(xiàn)在問(wèn)題來(lái)了:當(dāng)Offscreen組件從「失活」變?yōu)椤富顒?dòng)」,會(huì)觸發(fā)什么生命周期函數(shù)呢?

    答案是:componentDidMount以及:

     
     
     
     
    1. useEffect(() => { 
    2.    // 觸發(fā)這個(gè)邏輯... 
    3. }, []) 

    當(dāng)Offscreen組件從「活動(dòng)」變?yōu)椤甘Щ睢箷r(shí),會(huì)觸發(fā)componentWillUnmount與:

     
     
     
     
    1. useEffect(() => { 
    2.    // ... 
    3.    return () => { 
    4.      // 觸發(fā)這個(gè)邏輯... 
    5.    } 
    6. }, []) 

    所以,這些曾經(jīng)被認(rèn)為在組件生命周期中只會(huì)觸發(fā)一次的方法,由于Offscreen,在未來(lái)可能會(huì)多次觸發(fā)。

    這也是React提前在StrictMode中加上Strict Effect規(guī)則的原因。

    就像渣男變心前都會(huì)有些反常的舉動(dòng)。

    React18是真的挑戰(zhàn)

    不管是Offscreen還是Concurrent Mode,可以預(yù)見隨著v18的到來(lái),React會(huì)更強(qiáng)大,相應(yīng)的學(xué)習(xí)曲線會(huì)更陡峭。

    這既是機(jī)遇,也是挑戰(zhàn)。

    千萬(wàn)別等變化一股腦到眼前時(shí)再埋怨:

    你個(gè)渣男,當(dāng)初說(shuō)好一心一意只會(huì)觸發(fā)一次,現(xiàn)在為了妖艷新特性,背叛我們的諾言。

    到那時(shí)React只會(huì)拍拍屁股轉(zhuǎn)身,留下不羈的背影:

    參考資料

    [1]StrictMode文檔:

    https://zh-hans.reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects


    文章名稱:React要更新,就像渣男會(huì)變心
    網(wǎng)頁(yè)路徑:http://www.dlmjj.cn/article/djisihd.html