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
useEffectEventcan help isolate non-reactive logic from useEffect- Keep
useEffectEventprivate 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
useEffectEventto bypass dependency array - Only call
useEffectEventinsideuseEffect - Do not pass
useEffectEventto other components or hooks - Co-locate related
useEffectanduseEffectEvent
In general, understand what is reactive and non-reactive and do not abuse
useEffectEvent to avoid handling reactive variables in useEffect.