Why is this callback not being memoized in React?

24 Views Asked by At

I have a Next.js project with the following code in _app.tsx:

const Root = ({ Component, pageProps }) => {

  ...

  const handleHistoryChange = useCallback((url) => {
    console.log({ url });
  }, []);

  useEffect(() => {
    router.events.on('beforeHistoryChange', (url) => {
      handleHistoryChange(url);
    });

    return () => {
      router.events.off('beforeHistoryChange', handleHistoryChange);
    };
  }, [router.events, handleHistoryChange]);
}

Why is the console.log triggered 4 times every time the route is updated? How can I get it to only be triggered once?

1

There are 1 best solutions below

0
L_Cleo On

You should bind only ONCE the event listener, but you're binding every time the dependencies of the useEffect are updated: [router.events, handleHistoryChange].

Just remove the dependencies from your useEffect and your event should only be triggered once every beforeHistoryChange event.

 useEffect(() => {
    router.events.on('beforeHistoryChange', (url) => {
      handleHistoryChange(url);
    });

    return () => {
      router.events.off('beforeHistoryChange', handleHistoryChange);
    };
  }, []);