useMemo和useCallback的區別和使用


useMemo

 

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

將“創建”函數和依賴項添加到參數上使用備注,它僅會在某個依賴項改變時才重新計算備忘錄值。這種優化避免在每次渲染時都進行高開銷的計算。

也就是說useMemo可以讓函數在某個依賴項改變的時候才運行,這可以避免很多額外的開銷。舉個例子:

不使用useMemo

function Example() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
 
    const getNum = useMemo(() => {
        return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
    }, [count])
 
    return <div>
        <h4>總和:{getNum()}</h4>
        <div>
            <button onClick={() => setCount(count + 1)}>+1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}

使用useMemo后,成為count作為依賴值傳遞進去,此時僅count變化時才會重新執行getNum

useCallback

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

將內聯變量函數和依賴項替換為參數回調使用,回調返回該變量函數的備注,版本,該變量函數僅在某個依賴項改變時才會更新。當您將函數傳遞給經過優化的並使用引用替代性去避免非必要渲染(例如shouldComponentUpdate)的子組件時,則非常有用。


看起來似乎和useMemo差不多,我們來看看這兩個有什么異同:


useMemouseCallback接收的參數都是一樣,都是在其依賴項發生變化后才執行,都是返回緩存的值,區別在於useMemo返回的是函數運行的結果,useCallback返回的是函數。

useCallback(fn,deps)相當於useMemo(()=> fn,deps)

使用場景
頂部上面所說的,當你把某些函數傳遞給經過優化的並使用引用替代性去避免非必要渲染(例如shouldComponentUpdate)的子組件時,則非常有用。而父組件傳遞一個函數給子組件的時候,由於父組件的更新會導致該函數重新生成從而傳遞給子組件的函數引用發生了變化,這就會導致子組件也會更新,而很多時候子組件的更新是沒必要的,所以我們可以通過useCallback來緩存該函數,然后傳遞給子組件。舉個例子:

function Parent() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
 
    const getNum = useCallback(() => {
        return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
    }, [count])
 
    return <div>
        <Child getNum={getNum} />
        <div>
            <button onClick={() => setCount(count + 1)}>+1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}

const Child = React.memo(function ({ getNum }: any) {
    return <h4>總和:{getNum()}</h4>
})

使用useCallback之后,僅當count發生變化時Child組件才會重新渲染,而val變化時,Child組件是不會重新渲染的。

作者:威少_zv
鏈接:https://www.jianshu.com/p/b71e56ea2fda
來源:簡書

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM