useThread
One conversation's live state: polled history, the conversation record, and a send() with optimistic updates and idempotent retries.
Usage
import { useThread } from "@handset/react";
const thread = useThread(conversationId);
// Reply — from/to derive from the conversation itself:
await thread.send({ body: "On our way!" });Sends append an optimistic message immediately (pending: true), then swap in the API's accepted message. On failure the bubble flips to failed instead of vanishing. The optimistic local id doubles as the Idempotency-Key, so a retried request can never double-send.
Options
| Prop | Type | Default | Description |
|---|---|---|---|
| conversationId | string | null | — | First argument. null renders nothing and stops polling. |
| pollMs | number | 3000 | Poll interval. 0 disables polling. |
| limit | number | 100 | Max messages fetched per poll. |
Returns
| Prop | Type | Default | Description |
|---|---|---|---|
| conversation | Conversation | null | — | The conversation record, including opted_out. |
| messages | OutgoingMessage[] | — | Oldest first; includes optimistic entries. |
| send | (input: SendInput) => Promise<Message> | — | Reply in this conversation. Throws on failure. |
| isSending | boolean | — | True while a send is in flight. |
| isLoading | boolean | — | True until the first fetch resolves. |
| error | Error | null | — | Last fetch error. |
| refresh | () => Promise<void> | — | Force an immediate re-fetch. |