useEffectEvent - Refactor Your useEffect for Cleaner Code

Is your useEffect hook over 30 lines or packed with too many dependencies? Here we dive into how you can use useEffectEvent to refactor your useEffect logic.

TLDR

  • useEffectEvent can help isolate non-reactive logic from useEffect
  • Keep useEffectEvent private to the component
  • Be careful of hiding reactive logic in useEffectEvent

Fundamental Concepts

There are three fundamental concepts that you should know or recall before using useEffectEvent:

  • Reactive values are props, states & variables declared inside your component. And they can change due to a re-render.
  • Logic inside useEffect is reactive. And the main purpose of useEffect is to keep your component remain synchronized.
  • Logic inside event handlers are not reactive.

When should we use this?

When you identify there are non-reactive logic inside useEffect, it’s time to introduce useEffectEvent. For instance, your useEffect monitors changes of a prop like url, however, you need to log the url. Logging the url is probably the non-reactive logic and if you have metadata to log and the metadata is defined within the component that might be reactive. It’s best to use useEffectEvent to log the url and metadata.

How to use this?

Here’s a chat room that needs

function ChatRoom({ roomId, displayPreference }) {
    const onConnected = useEffectEvent((roomId) => {
        trackEvent({
            roomId,
            displayPreference,
        });
    });

    useEffect(() => {
        const connection = createConnection(serverUrl, roomId);
        connection.on("connected", () => {
            onConnected();
        });

        connection.connect();
        return () => connection.disconnect();
    }, [roomId]);

    return <h1>Welcome to the {roomId} room!</h1>;
}

Best practices

  • Pass reactive values explicitly as arguments to useEffectEvent
  • Do not use useEffectEvent to bypass dependency array
  • Only call useEffectEvent inside useEffect
  • Do not pass useEffectEvent to other components or hooks
  • Co-locate related useEffect and useEffectEvent

In general, understand what is reactive and non-reactive and do not abuse useEffectEvent to avoid handling reactive variables in useEffect.

Sources