Skip to main content

Command Palette

Search for a command to run...

React: Hooks - useCallback

Published
•1 min read•View as Markdown

在 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

2 views

More from this blog

Vite: vite-plugin-html的bugs和坑

因為工作要用Vite去生成一個mpa專案且根據頁面不同,動態生成不同 <title> 的HTML,所以就找了一個套件──vite-plugin-html,結果因為套件好像很久沒維護,隨著Vite升級又多了一些有的沒的bug,順手來記錄一下。 template delete 像我第一個就是遇到生成的時候template HTML也會被刪掉,後來看到issue上也有人反映,還好有好心人士解決這個問題,

Feb 26, 20261 min read5

Lun's Blog

82 posts

Notes for web development