我們都知道如何使用 React.useCallback 和 React.useMemo,但有時我們會很困惑應該選擇哪一個。
這裡我將透過一些案例來幫助大家了解在某些特定情況下我們應該使用什麼鉤子函數。
import React, { useState } from 'react' export default function App() { const [num1, setNum1] = useState(10) const [num2, setNum2] = useState(12) return <div>{num1 + num2}</div> }
在上面的簡單範例中,我們可以在 HTML 元素部分透過 num1 + num2 求和,但如果我們有一些更複雜的計算邏輯,我們不應該再這樣做了。
import React, { useState, useMemo } from 'react' export default function App() { const [num1, setNum1] = useState(10) const [num2, setNum2] = useState(12) const sum = useMemo(() => { const _num1 = Number(num1), _num2 = Number(num2) if (Number.isNaN(_num1) || Number.isNaN(_num2)) { return "check your num's type" } return _num1 + _num2 }, [num1, num2]) return <div>{sum}</div> }
在這個範例程式碼區塊中,我們選擇useMemo 來保留num1 + num2 的結果值,但我們加入了一些類型檢查邏輯,因為我們不能完全相信num1 或num2 的類型將是數字,所以當類型出錯時,我們將顯示佔位符文字。
在這種情況下,你無法在HTML部分用一行簡單的程式碼實現這種效果。當然,你可以在HTML部分用條件運算子寫一些邏輯程式碼(JSX允許你這麼做),但代價是犧牲程式碼的可讀性。
因此,useMemo 是處理這種情況的好選擇。
好吧,讓我們來討論一個更複雜的案例。
import React, { useState, useMemo } from 'react' export default function App() { const [num1, setNum1] = useState(10) const [num2, setNum2] = useState(12) const [num3, setNum3] = useState(100) const [num4, setNum4] = useState(120) const sum1 = useMemo(() => { const _num1 = Number(num1), _num2 = Number(num2) if (Number.isNaN(_num1) || Number.isNaN(_num2)) { return "check your num's type" } return _num1 + _num2 }, [num1, num2]) return ( <> <div>{sum1}</div> <div>{num3 + num4}</div> </> ) }
如你所見,我們這裡有 num3 和 num4 來渲染它們的總和。如果我們還想重複使用num1 + num2的邏輯,該怎麼辦呢?當然,我們仍然可以使用 useMemo 來定義一個 sum2,但重複使用邏輯來驗證 num 的類型並不是一個好主意。因此我們需要將驗證邏輯從 useMemo 中分離出來。然後 useCallback 出現了!
import React, { useState, useCallback } from 'react' const validteNumAndSum = (number1, number2) => { const _num1 = Number(number1), _num2 = Number(number2) if (Number.isNaN(_num1) || Number.isNaN(_num2)) { return "check your num's type" } return _num1 + _num2 } export default function App() { const [num1, setNum1] = useState(10) const [num2, setNum2] = useState(12) const [num3, setNum3] = useState(100) const [num4, setNum4] = useState(120) const sumFunc = useCallback(validteNumAndSum, []) return ( <> <div>{sumFunc(num1, num2)}</div> <div>{sumFunc(num3, num4)}</div> </> ) }
如你所見,我們使用useCallback傳回一個新函數,其邏輯是驗證num的類型併計算總和,並且我們可以輕鬆地在HTML部分重用這個validteNumAndSum函數。
好的,讓我們進入結論部分:
如果你可以輕鬆地進行計算(數學或更複雜的情況),則不需要 useMemo 和 useCallback。
如果你的計算邏輯比較複雜,只需要計算一次,你可以選擇useMemo鉤子來封裝你的計算過程並回傳一個簡單的結果。
但如果您多次使用相同的邏輯,您可以選擇 useCallback 傳回一個記憶的函數,以便在您的元件中重複使用它。
對於 useCallback 的情況我感到非常抱歉。我犯了一個錯誤,那就是解釋何時選擇 useCallback 並創建了一個錯誤的範例案例。
這裡我再試一次。
import React, { useState, useCallback } from 'react' export default function App() { const [base, setBase] = useState(0) const [num1, setNum1] = useState(10) const [num2, setNum2] = useState(12) const [num3, setNum3] = useState(100) const [num4, setNum4] = useState(120) const sumFunc = useCallback( (number1, number2) => { const _num1 = Number(number1), _num2 = Number(number2) if (Number.isNaN(_num1) || Number.isNaN(_num2)) { return "check your num's type" } return _num1 + _num2 + base }, [base], ) return ( <> <input type="number" value={base} onChange={e => { setBase(Number(e.target.value)) }} /> <div>{sumFunc(num1, num2)}</div> <div>{sumFunc(num3, num4)}</div> </> ) }
在上面的程式碼中,我們添加一個基數作為另一個變數數據,並且每個和都應該與基值相加,並且我們有一個輸入來更改基值,因此每次更改基數時,sumFunc都會也可以修改,我們可以用它來計算正確的結果。
所以我會更新我關於useCallback的結論:如果我們只是需要重用一些邏輯,我們可以將這個邏輯封裝成一個函數,甚至將它作為一個util函數從組件中分離出來,以便在任何地方重用它。而如果我們的邏輯仍然依賴組件的某些變量,我們可以使用 useCallback 來封裝邏輯並傳回一個記憶的新函數。
以上是useCallback VS useMemo的詳細內容。更多資訊請關注PHP中文網其他相關文章!