Separating Events from Effects

Some code inside an effect is reactive and some is not. A chat component that connects to roomId and shows a notification styled with the current theme reads two values, but only one should cause a reconnection. List theme and switching to dark mode drops the connection; leave it out and the notification uses whatever theme was current when the effect last ran.

useEffectEvent, added in React 19.2 7,897 , marks the non-reactive part. The function it returns always sees the latest props and state, yet never counts as a dependency.

Reconnecting only when the room changesJavaScript
import { useEffect, useEffectEvent } from 'react';
function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification('Connected!', theme);      // always the latest theme
  });
  useEffect(() => {
    const conn = createConnection(roomId);
    conn.on('connected', () => onConnected());
    conn.connect();
    return () => conn.disconnect();
  }, [roomId]);                                 // theme deliberately absent
  return <Messages roomId={roomId} />;
}

The rules are narrow on purpose, because an effect event is a hole in the reactive model:

Read the split out loud: "connect to the room, and when that happens, notify with the current theme." Before the comma is the effect; after it is the event.