前天提到,useMemo
和useCallback
通常會放在一起討論,
那是因為,他們本質是差不多的東西,只是差別在於回傳值還是回傳函數。
那麼,我們就說完了。
明天見!
抱歉...還沒湊滿三百個字,我又回來了。
話不多說,直接進入正題!
為什麼需要useMemo
呢?就是老樣子渲染的問題,useMemo
只會在dependencies改變的時候重新計算,
其他時候,他存好的值就是存好了,不會亂動。
寫法跟useCallBack
很像,如下:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
那麼,有沒有useMemo
的差別在哪呢?
來看一下code,來源是w3schools。(我有小小小小小調整一下)
並且,附上渲染出來的樣子。
(這次不能一眼略過了,要認真看一下)
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const calculation = expensiveCalculation(count)
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = () => {
console.log(count)
setTodos((t) => [...t, "New Todo"+count]);
};
return (
<div>
<div>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Add Todo</button>
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
{calculation}
</div>
);
};
const expensiveCalculation = (num) => {
console.log("Calculating...");
return num = num+1
};
在這裡,我就不多細說那些建立了甚麼function或是甚麼state的內容了,
而是聚焦在運用useMemo與否的差異。
在這個例子裏面,我們expensiveCalculation
如果被觸發,就會console.log("Calculating...")
,
也就是說,如果我們點擊呼叫increment
這個函數讓count+1,就會console.log("Calculating...")
,
這很正常,但我們會發現,
我如果新增一個todos,也會console.log("Calculating...")
,
就只是因為,我在todos後面也用到了count
,但我在新增一個todos的時候,明明沒有改變count啊!
這時候,就需要派useMemo
出場了。
我們只需要把這行,改成用useMemo
的方法寫就好了。
const calculation = expensiveCalculation(count)
變成這樣:
const calculation = useMemo(() => expensiveCalculation(count), [count]);
這樣,因為todos沒有改變count
,dpendencies
沒有被改變的情況下,useMemo
就會好好的存著值。
那麼,這次就真的,明天見了!