@void-snippets/react

useSocketListener

Subscribe to server events with stale-closure-safe ref pattern.

#What it does

Subscribes to a server event for the lifetime of the component. The listener is added on mount and removed on unmount — no manual cleanup. Uses a ref internally so inline arrow functions are always safe — no stale closure bugs.

#Signature

typescript
useSocketListener(
  event:    keyof TServerEvents,
  handler:  TServerEvents[typeof event],
  options?: { enabled?: boolean },
): void

#Parameters

ParameterTypeDefaultDescription
eventkeyof TServerEventsrequiredThe event name to listen for.
handlerInferred functionrequiredCalled when the event fires. Always uses the latest version — useCallback is not needed.
options.enabledbooleantruePass false to deactivate without unmounting. Flip dynamically.

#Example

tsx
function ChatRoom({ roomId }: { roomId: string }) {
  const [messages, setMessages] = useState<Message[]>([]);
  const { isConnected } = useSocketConnection();

  // Always active while mounted — inline arrow is safe
  useSocketListener('new-message', (data) => {
    setMessages(prev => [...prev, { text: data.text, from: data.from }]);
  });

  // Only active when connected AND in a room
  useSocketListener('user-joined', (userId) => {
    toast.info(`${userId} joined`);
  }, { enabled: isConnected && !!roomId });

  return <MessageList messages={messages} />;
}