1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        useEffect, useCallback, useMemo三者有何區(qū)別?

        共 3018字,需瀏覽 7分鐘

         ·

        2021-03-20 16:24

        原文:https://segmentfault.com/a/1190000039657107


        關(guān)注公眾號 前端人,回復(fù)“加群

        添加無廣告優(yōu)質(zhì)學(xué)習(xí)群

        背景

        在目前的react開發(fā)中,很多新項(xiàng)目都采用函數(shù)組件,因此,我們免不了會接觸到hooks。此外,Hooks也是前端面試中react方面的一個高頻考點(diǎn),需要掌握常用的幾種hooks。

        常用的有

        • 基本:useState, useEffect, useContext
        • 額外:useCallback, useMemo, useRef

        剛接觸公司的react項(xiàng)目代碼時,發(fā)現(xiàn)組件都是用的函數(shù)組件,不得不去學(xué)習(xí)hooks,之前只會類組件和react基礎(chǔ)

        其中useState不用說了,很容易理解,使我們在函數(shù)組件中也能像類組件那樣獲取、改變state

        項(xiàng)目中很多地方都有useEffect, useCallback, useMemo,初看時感覺這三個都是包著一個東西,有它們跟沒有它們感覺也沒什么區(qū)別,很難分清這三個什么時候要用

        所以這里就略微總結(jié)一下,附上一點(diǎn)個人在開發(fā)過程中的理解。

        其實(shí)這三個區(qū)別還是挺明顯的:

        useEffect

        useEffect可以幫助我們在DOM更新完成后執(zhí)行某些副作用操作,如數(shù)據(jù)獲取,設(shè)置訂閱以及手動更改 React 組件中的 DOM 等

        有了useEffect,我們可以在函數(shù)組件中實(shí)現(xiàn) 像類組件中的生命周期那樣某個階段做某件事情,具有:

        • componentDidMount
        • componentDidUpdate
        • componentWillUnmount

        基本用法

        useEffect(() => {
            console.log('這是一個不含依賴數(shù)組的useEffect,每次render都會執(zhí)行!')
        })

        useEffect 規(guī)則

        • 沒有傳第二個參數(shù)時,在每次 render 之后都會執(zhí)行 useEffect中的內(nèi)容
        • useEffect接受第二個參數(shù)來控制跳過執(zhí)行,下次 render 后如果指定的值沒有變化就不會執(zhí)行
        • useEffect 是在 render 之后瀏覽器已經(jīng)渲染結(jié)束才執(zhí)行
        • useEffect 的第二個參數(shù)是可選的,類型是一個數(shù)組
        • 根據(jù)第二個參數(shù)的不同情況,useEffect具有不同作用

        1. 空數(shù)組

        useEffect 只在第一次渲染時執(zhí)行,由于空數(shù)組中沒有值,始終沒有改變,所以后續(xù)render不執(zhí)行,相當(dāng)于生命周期中的componentDidMount

        useEffect(() => { 
         console.log('只在第一次渲染時執(zhí)行') }, []
        );

        2. 非空數(shù)組

        無論數(shù)組中有幾個元素,數(shù)組中只要有任意一項(xiàng)發(fā)生了改變,useEffect 都會調(diào)用

        useEffect(() => { 
         getStuInfo({ id: stuId }); }, [getStuInfo, stuId]
        );

        getStuInfo或者stuId改變時調(diào)用getStuInfo函數(shù)

        useCallback 和 useMemo

        相同點(diǎn):

        useCallback 和 useMemo 都是性能優(yōu)化的手段,類似于類組件中的 shouldComponentUpdate,在子組件中使用 shouldComponentUpdate, 判定該組件的 props 和 state 是否有變化,從而避免每次父組件render時都去重新渲染子組件。

        區(qū)別:

        useCallback 和 useMemo 的區(qū)別是useCallback返回一個函數(shù),當(dāng)把它返回的這個函數(shù)作為子組件使用時,可以避免每次父組件更新時都重新渲染這個子組件,

        const renderButton = useCallback(
             () => (
                 <Button type="link">
                    {buttonText}
                 </Button>

             ),
             [buttonText]    // 當(dāng)buttonText改變時才重新渲染renderButton
        );

        useMemo返回的的是一個值,用于避免在每次渲染時都進(jìn)行高開銷的計(jì)算。例:

        // 僅當(dāng)num改變時才重新計(jì)算結(jié)果

        const result = useMemo(() => {
            for (let i = 0; i < 100000; i++) {
              (num * Math.pow(215)) / 9;
            }
        }, [num]);

        補(bǔ)充:

        什么時候用useCallback和useMemo進(jìn)行優(yōu)化

        任何的優(yōu)化都是有代價的,useCallback和useMemo雖然能夠避免非必要渲染,但為此也付出了成本,比如保留額外的依賴數(shù)組;保留舊值的副本,以便在與先前依賴相同的情況下返回……

        考慮到這些,在我們的項(xiàng)目中什么時候用useCallback和useMemo進(jìn)行優(yōu)化呢?

        目前所在的公司,項(xiàng)目中所有地方都用了useCallback和useMemo,就這塊問了一下mentor,他給出的答復(fù)是這樣的:

        就算有比對代價也比較小,因?yàn)槟呐率菍ο笠仓皇且帽容^。

        我覺得任何時候都用是一個好的習(xí)慣,但是大部分時間不用也沒什么大問題。但是如果該函數(shù)或變量作為 props 傳給子組件,請一定要用,避免子組件的非必要渲染

        然后要記得 React 的工作方式遵循純函數(shù),特別是數(shù)據(jù)的 immutable,因此,使用 memo 很重要。

        但大部分時候都不足以成為性能瓶頸


        • 回復(fù)資料包領(lǐng)取我整理的進(jìn)階資料包
        • 回復(fù)加群,加入前端進(jìn)階群
        • console.log("點(diǎn)贊===點(diǎn)看===你我都快樂")
        • Bug離我更遠(yuǎn)了,下班離我更近了

        瀏覽 232
        1點(diǎn)贊
        評論
        1收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        1點(diǎn)贊
        評論
        1收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产传媒成人 | 放荡的美妇一区二区三区最新章节 | 狠狠躁日日躁夜夜躁A片无码视频 | 91成人久久国产综合一区二区三区 | 大乱斗肉寡妇怎么出装最好看视频 | 最新一级片 | 小受男被多男摁住灌浓精视频 | 国产精品久久久久久久岛一本 | 操比免费看 | 日本黄色A片 |