React函式式元件值之useMemo()和useCallback()
阿新 • • 發佈:2020-12-23
一、基礎用法
- useMemo可以保證依賴的值未發生改變的時候,不觸發值改變。
- useCallback可以保證依賴的值未發生改變的時候,不觸發函式引用的改變。
1 //當count變化,sum的值會改變
2 const sum = useMemo(() => {
3 return count + 1;
4 }, [count]);
5 //當count變化,getSum函式會改變
6 const getSum = useMemo(() => {
7 return count + 1;
8 }, [count]);
第二引數含義:
- 不傳陣列,每次更新都會重新計算
- 空陣列,只會計算一次
- 依賴對應的值,當對應的值發生變化時,才會重新計算
二、應用場景
React的函式式元件在直接使用useState或使用useEffect間接呼叫useState時,會導致整個函式的重新執行。其中,函式元件包裹的所有的變數、常量、函式都會被重新初始化,相當於props整體更新,所有元件內的子元件重新繪製。但並不是每個子元件都有必要重繪,有的根本沒有變化,這時,就需要使用useMemo和useCallback保證函式元件內常量與函式的唯一性。
1 import React, { useState, memo, useMemo, useCallback } from 'react'
2 const Child = memo((props) => {
3 console.log(props);
4 return (
5 <div>
6 <input type="text" onChange={props.onChange}/>
7 </div>
8 )
9 })
10 const Parent = () => {
11 const [count, setCount] = useState(0)
12 const [text, setText] = useState('')
13 const handleOnChange = useCallback((e) => {
14 setText(e.target.value)
15 },[])
16 return (
17 <div>
18 <div>count: {count}</div>
19 <div>text: {text}</div>
20 <button onClick={() => {
21 setCount(count + 1)
22 }}>+1</button>
23 <Child onChange={handleOnChange} />
24 </div>
25 )
26 }
27 function App() {
28 return <div><Parent /></div>
29 }
30 export default App
上面程式碼中,handleOnChange被快取了下來,儘管父元件更新了,但是拿到的handleOnChange還是同一個,對比useMemo,useMemo快取的是一個值,useCallback快取的是一個函式,是對一個單獨的props值進行快取,memo快取的是元件本身,是站在全域性的角度進行優化。
需要注意的是,useMemo 會在渲染的時候執行,而不是渲染之後執行,這一點和 useEffect 有區別,所以 useMemo 不建議有 副作用相關的邏輯。
useMemo根據依賴的值計算出結果,當依賴的值未發生改變的時候,不觸發狀態改變。一般開發,在向子元件傳遞函式props時,每次 render 都會建立新函式,導致子元件不必要的渲染,浪費效能,這個時候,就是 useCallback 的用武之地了,useCallback 可以保證,無論 render 多少次,我們的函式都是同一個函式,減小不斷建立的開銷。