[Note] React - Hooks: useCallback


Posted by urlun0404 on 2022-10-19

React.memo的文章有提到,每次component更新(re-evaluate)都會產生長得一模一樣的新函式物件,所以當新的函式物件當作props傳入child component,child component會因為傳入的函式物件不同而跟著parent component更新。

那要如何讓component更新時不會產生新的函式物件?

答案就是用 useCallback


useCallback

useCallback 是React用來儲存函式物件的hook,並能保證每次component更新時使用的都是和前一次更新相同的函式,也就是同一個位址的函是物件。

// App.js (parent component)
import {useState, useCallback} from 'react';
import Me from './Me';
import Button from './Button';


export default function App(){
    console.log('App loads');

    const [isMe, setIsMe] = useState(false);

    // Use useCallback hook
    const addMe = useCallback((event) => {
    event.preventDefault();
    setIsMe((prevMe) => !prevMe);
    }, []);

    return (
        <>
            <h1>h1 always here</h1>
            <Me me={false}/>
            <Button onClick={addMe}>Click and Add Me!</Button>
        </>
    )
}

useCallback 讓component更新時不會創造一個長得一模一樣卻是儲存在不同地方的新函式,也因此每次傳入Button component的addMe函式props就會是相同的。

此外,這篇文章 在討論如何正確地用 removeEventListener 移除事件監聽器,而這個問題的原因就是每次Component更新會產生看起來名稱相同、但其實是不同物件的函式,因此沒辦法正常使用 removeEventListener。其中一個解決辦法就是用 useCallback hook;而文章下面留言有提到另一個辦法是使用useEffect來處理這個問題,而且會處理的會更好。


References


Live Demo


#frontend #React #hook #note







Related Posts

引領團隊前進:北極星與路標們

引領團隊前進:北極星與路標們

菜比八寫後端(3) - MySQL key與正規化

菜比八寫後端(3) - MySQL key與正規化

Selenium with JS and infinite scroll

Selenium with JS and infinite scroll


Comments