React Best Practices

Chapter 3 · Practice 3 of 4

Keep dependency arrays honest and use useEffectEvent for non-reactive logic

From Effects, and when you do not need one

Why it matters

Every reactive value an effect reads must be in its dependency array. Leaving one out to stop the effect from re-running causes stale values and bugs that are hard to trace. Let the eslint-plugin-react-hooks rules check this for you.

Sometimes part of an effect should read the latest value without re-running the effect. Move that part into an Effect Event with useEffectEvent:

  • Call the event only from inside effects.
  • Do not list it as a dependency.

Example

TSX
function ChatRoom({ roomId, muted }: Props) {
  const onConnected = useEffectEvent(() => {
    if (!muted) showNotification('Connected');
  });

  useEffect(() => {
    const conn = createConnection(roomId);
    conn.on('connected', onConnected);
    conn.connect();
    return () => conn.disconnect();
  }, [roomId]); // muted is read through the Effect Event
}