@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
| Parameter | Type | Default | Description |
|---|---|---|---|
event | keyof TServerEvents | required | The event name to listen for. |
handler | Inferred function | required | Called when the event fires. Always uses the latest version — useCallback is not needed. |
options.enabled | boolean | true | Pass 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} />;
}