日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

react组件放在数组中_为什么要在函数组件中使用React.memo?

發布時間:2025/3/19 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react组件放在数组中_为什么要在函数组件中使用React.memo? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這里提一下,如果大家看到這個標題有所疑惑的話,可以花點時間看一下本篇文章。反之呢如果是看到標題第一時間就反映出結論的話,就可以去get其他文章的知識點了

那么接下來就不廢話了,直接長刀直入,進入正題!

初探memo

首先讓我們用一個例子走進React.memo的世界

呆呆的函數組件 - 沒有使用memo

對于一個函數組件來說,如果沒有使用React.memo就好比是一個人沒有腦子,就笨笨的呆呆的

不信我們就來看下面的Demo

點擊訪問演示Demo

讓我們來分析下上圖發生的流程:

  • 頁面第一次加載,渲染App組件和B組件,控制臺打印效果如上圖
  • 點擊按鈕,改變App組件內的值。App組件和B組件全都發生更新
  • 那么問題就來了,按正常邏輯來說,應該是這樣的流程才對:

  • 頁面第一次渲染,App組件和B組件分別更新,并打印
  • App組件內的數據發生變化所以,App組件重新渲染
  • 改變的數據和B組件毛關系沒有,B組件維持原狀,不進行更新渲染
  • but理想異常豐滿的,現實十分骨干的。 事實就是不但App組件發生了更新,B組件也跟著進行了更新,這不是我們想要的,因為對于B組件來說:明明老子啥都沒干,卻還非要我再重新穿一遍衣服?

    無效渲染的原因

    那么造成無效渲染的原因是啥呢?

    其實簡單說來是這樣的:

    函數組件本身沒有識別prop值的能力,每次父組件更新的時候都相當于是給子組件一個新的prop值。所以就相當于B組件這小子因為沒帶腦子(React.memo),是個呆呆的二傻子,所以他做為一個普通組件,就沒有分別prop的能力,當他看到別人都更新了也就跟著把自己也造了一遍,因此就會造成上面中的問題。

    給憨憨帶上腦子 - 使用memo進行包裹

    給函數組件帶上腦子 當我們給一個函數組件帶上腦子的時候,就想下面這樣

    import React form 'react';const FuncComponent = ()=>{return

    火熱很火辣

    }export default React.memo(FunComponent);

    就不會發生上面那種,無腦render組件的情況了

    試著把上面demo中B組件代碼里最后一行的注釋放開試一下吧

    然后像上面一樣再次點擊一下按鈕,看看控制臺的打印結果:

    Yep! 只更新了App組件,符合預期!

    那么到底是為什么造成的這種原因呢

    所以到這里還不算完,讓我們進一步升溫

    激情升溫 - 深入探索

    到這里其實我們還是不太清楚memo是怎么做到避免無效更新的,接下來我們就來扒一扒!

    class組件中的性能優化點

    不知道大家有沒有發現class組件中也有一個這樣作用的東西,叫做PureComponent,它的功能和memo是一毛一樣的。

    來回顧一下,我們在class組件中經常用到的寫法:

    import React, {PureComponent} from 'react';class Demo extends PureComponent {// 性能優化點shouldComponentUpdate(nextProps, nextState){// 默認始終返回truereturn true; }render() {return

    聽懂掌聲

    }}

    總的來說其實PureComponnet和memo都是通過對props值的淺比較來決定該組件是否需要更新的。

    如果我們在class組件中,不主動使用PureComponent,也可以手動的去決定該組件是否更新,具體做法:

    在生命周期shouldComponentUpdate,來通過對當前porps以及state值的對比,然后返回一個布爾值(true或者false)來決定該組件是否更新。

    其實PureComponent組件就是把這對比值的部分功能幫我們完成了,方便我們直接使用,而不用再去手動的去寫代碼進行類似的優化。

    memo的功能實現

    這里是我的猜想哈,memo的原理和PureComponent應該是一樣的,從開發者的角度去想,既然class組件有這樣一個優化方法,那既然要推行Hook,函數組件也必定需要一個類似功能的方法去幫助大家減少代碼優化的工作量。所以感覺兩者在功能的實現上應該大部分都是一致的。 這里也放上一段React中PureComponent進行淺比較的代碼,方便大家進一步理解

    function shallowEqual (objA: mixed, objB: mixed): boolean { // 這里的is是判斷兩個值是否相等,只不過是對 + 0 和 - 0,以及 NaN 和 NaN 的情況進行了特殊的處理封裝,目前react源碼中好像有一套新的is判斷 if (is (objA, objB)) { return true; } // 判斷是否為對象類型 if ( typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null ) { return false; } // 比較兩個對象的,屬性數量是否相等 const keysA = Object.keys (objA); const keysB = Object.keys (objB); if (keysA.length !== keysB.length) { return false; } // 比較兩個對象的的屬性是否相等,值是否相等 for (let i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call (objB, keysA [i]) || !is (objA [keysA [i]], objB [keysA [i]]) ) { return false; } } return true;}

    這就是react中進行淺層比較的源碼,也是PureComponent和memo決定是否更新組件的重要依據。

    memo配合useMemo、useCallback

    一般在項目的優化實踐中,memo包裹的函數組件都是要配合useMemo和useCallback來使用的

    對于useMemo和useCallback其實我不準備長篇大幅的講述了,因為社區已經有很多不錯的文章了,大家可以搜來看一下。 我這里只做一個說人話的簡單介紹就好了

    useCallback

    const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], );

    返回值是一個函數(memoizedCallback),這個函數就是作為第一個參數傳進去的那個。區別就是作為返回值的這個函數是一個memoized的版本,用人話理解就是:保持了函數的引用。不會在組件更新時,去重新聲明函數,從而改變在內存中的引用地址。

    除非是第二個參數數組里的依賴項發生改變,否則這個做為返回值的函數(memoizedCallback)就一直保持原先的狀態

    應用場景

    經常使用在父組件A向子組件B傳遞一個函數作為prop值的時候

    父組件A:

    import React,{ useCallback } form 'react';const A = () => {return ( // 如果不使用useCallback包裹的話,每次A的更新,都會重新聲明這個handleClick的這個函數,導致B組件無效的更新 //doSomething,[x,xx]) }; );}export default A;

    子組件B:

    import React,{ memo } form 'react';const B = (props) => {const { handleClick } = props;return 卑微小B在線被Diss;}// 這里需要注意,要配合memo使用,否則的話不帶腦子的B組件會始終認為傳遞過來的prop值都是一個全新的export default memo(B);

    useMemo

    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

    其實和useCallback很像,只不過是useMemo返回的是一個,而不是一個函數

    useCallback 的第一個參數是函數,這個函數的返回值會作為useMemo的返回值memoizedValue)

    除非是第二個參數數組里的依賴項發生改變,否則這個做為返回值(memoizedValue)就一直保持原先的值

    useCallback能做的事useMemo都能做,但是還是推薦各司其職

    const fn = useCallback( () => //doSomething , [x,xx])// 相當于const fn = useMemo( ()=> () => //doSomething , [x,xx])// 因為useMemo的返回值是第一個函數的返回值,所以只要讓第一個參數的函數返回一個函數就可以達到useCallback的效果

    結尾 需要這些資料,可以私信 666 領取

    總結

    以上是生活随笔為你收集整理的react组件放在数组中_为什么要在函数组件中使用React.memo?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。