Events
Listen to events that the server pushes, with arguments typed from the contract.
An event is a message that the server pushes to the client. You declare each event in the contract with event<Args>(). The handler gets the typed arguments. Only events that the contract declares reach a handler.
Listen to an event
useSignalREffect subscribes to one event of one hub. The subscription ends when the consumer ends. This sample shows the messages of a room:
import { useState } from "preact/hooks";
import type { ChatMessage } from "./contract";
import { useSignalREffect } from "./client";
export function Messages({ roomId }: { roomId: string }) {
const [messages, setMessages] = useState<ChatMessage[]>([]);
useSignalREffect("/hubs/rooms", "MessageReceived", (message) => {
if (message.roomId === roomId) setMessages((all) => [...all, message]);
});
return (
<ul>
{messages.map((m, index) => (
<li key={index}>{m.user}: {m.text}</li>
))}
</ul>
);
}The helper also counts as a consumer of the hub. See Lazy hubs.
Handlers across rebuilds
The library keeps the handlers in the session, not in the connection. A reconnect or a rebuild of the connection does not remove them. After a rebuild, the new connection delivers events to the same handlers.
You can register several handlers for one event, in one component or in many. Each handler gets every event. Your code must not rely on the order in which the handlers run.
Latest handler
The helper reads the latest handler on each render. A new function on each render causes no resubscribe. You do not need useCallback.
Errors in a handler
An error in a handler does not stop other handlers and does not break the connection. The library passes the error to onError with info.source set to "callback". A promise that a handler returns and that rejects gets the same treatment. For the full picture, see Recovery.