是的,useCallback
的目的是允許函數(shù)在渲染之間保持其引用,除非你指定的依賴項(xiàng)發(fā)生了變化。
例如,如果你有一個(gè)函數(shù)f(x,y)=>x y
,你可以使用空的依賴數(shù)組useCallback((x,y)=>x y,[ ])
,這個(gè)函數(shù)將永遠(yuǎn)不會(huì)改變。它始終會(huì)產(chǎn)生一致的行為,因?yàn)樗皇褂闷鋮?shù)來(lái)解析輸出。但是,如果你有另一個(gè)函數(shù)h
和另一個(gè)外部值z
,它可能會(huì)發(fā)生變化,而h
定義為h(x ,y)=>x y z
,那麼你需要將z
包含在依賴項(xiàng)中,以便如果z
發(fā)生變化,從useCallback
返回的函數(shù)將具有新的引用。
因此,useCallback
的用途通常是當(dāng)你傳遞函數(shù)時(shí),它不會(huì)觸發(fā)子元件重新渲染,或者當(dāng)你在子元件的useEffect
宣告中使用函數(shù)作為依賴項(xiàng)時(shí)。如果函數(shù)內(nèi)部的操作很昂貴,那麼useCallback
就不太有用了,你應(yīng)該單獨(dú)對(duì)結(jié)果進(jìn)行記憶。
關(guān)於ref
的事情,我認(rèn)為在依賴項(xiàng)中包含ref
並不會(huì)有任何作用,它就像數(shù)組為空一樣。也許如果ref
被儲(chǔ)存在狀態(tài)中,可能會(huì)有用,但我不太確定。
這裡有一個(gè)連結(jié)https://stackblitz.com/edit/stackblitz-starters-wwyw9f?file=src/App.tsx,裡面有一些例子,也許有用。
如果可能會(huì)被刪除,我也可以將其貼過(guò)來(lái)。
import * as React from 'react'; import './style.css'; export default function App() { //x and y to be used as function arguments const [x, setX] = React.useState(0); const [y, setY] = React.useState(0); //z is variable also used in function calculation but not as an argument const [z, setZ] = React.useState(0); const ref = React.useRef<number>(0); //counter to see how many times function updates //will start at 2 cause strict mode but that's no issue really const [i, setI] = React.useState(0); //function to add x and y from args and add z from state const fn = React.useCallback( (x: number, y: number) => { // console.log(`${x}+${y}`); return x + y + z; }, [z] // if you remove z and update it get wrong result ); //update fn count on fn change React.useEffect(() => { setI((i) => i + 1); }, [fn]); React.useEffect(() => { console.log('nice'); return () => console.log('ref cleanup'); }, [ref]); return ( <div> <pre>{JSON.stringify({ x, y, z })}</pre> <button onClick={() => setX((x) => x + 1)}> x ++</button> <button onClick={() => setY((y) => y + 1)}> y ++</button> <button onClick={() => setZ((z) => z + 1)}> z ++</button> <pre>x+y+z={fn(x, y)}</pre> <pre>fnCount:{i}</pre> <button onClick={() => { ref.current = ref.current++; }} > ref++ </button> </div> ); }
希望能對(duì)你有幫助