ThreadContext
ThreadContext tells a component which thread it renders in. Thread provides it, and useThreadContext() reads it. Components that work in both a channel and a thread, such as MessageList and MessageComposer, use it to tell the two apart: thread is set inside a Thread and undefined everywhere else.
Best practices
- Read it with
useThreadContext(). It doesn't throw outside aThread, so one component can render in a channel and in a thread. - Check
threadto know whether a component is in a thread. Read the list and the composer withuseMessagePaginator()anduseMessageComposer(), which already return the thread's inside it, rather than branching yourself. - Read the thread's state with
useStateStore(thread?.state, selector)and a selector declared at module scope. The context holds theThreadinstance, which changes only when the thread does. - Let
Threadprovide it.Threadalso loads and activates the thread and provides the contexts the list and the composer need.ThreadProviderdoes none of that. - In a
ThreadListrow, useuseThreadListItemContext(). Rows aren't inside aThread, souseThreadContext()returns no thread there.
Basic usage
This screen header shows the parent message's author in a thread and nothing in a channel:
import { Text } from "react-native";
import type { ThreadState } from "stream-chat";
import { useStateStore, useThreadContext } from "stream-chat-react-native";
const parentMessageSelector = ({ parentMessage }: ThreadState) => ({
parentMessage,
});
export const ThreadTitle = () => {
const { thread } = useThreadContext();
const { parentMessage } =
useStateStore(thread?.state, parentMessageSelector) ?? {};
if (!thread) return null;
return (
<Text numberOfLines={1}>
Thread with {parentMessage?.user?.name ?? parentMessage?.user?.id}
</Text>
);
};Render it as the first child of Thread. useStateStore returns undefined when it gets no store, so the selector's result is read with ?? {} outside a thread.
Values
| Value | Type | Description |
|---|---|---|
thread |
Thread |
The Thread instance from stream-chat that the Thread around the component renders, or undefined outside one. |
allowThreadMessagesInChannel |
boolean |
The Thread prop, true by default: whether the composer shows the "Also send to channel" checkbox. false outside a Thread. |
Outside a Thread, useThreadContext() returns { thread: undefined, allowThreadMessagesInChannel: false }. ThreadContextValue is the type of the value, and ThreadContext itself is exported, so useContext(ThreadContext) returns the same as useThreadContext().
The thread's own data is in its stores, not in this context:
| To read | Store |
|---|---|
| The parent message, the reply count, participants, read state | thread.state |
| The loaded replies and whether more are loading | thread.messagePaginator.state |
| The latest reply | thread.messagePaginator.aggregateState |
| The reply being written | thread.messageComposer and its parts |
Thread and thread manager lists the fields of thread.state.
ThreadProvider
ThreadProvider sets the context for its children. It takes a value of type ThreadContextValue:
| Prop | Type | Default | Description |
|---|---|---|---|
value |
ThreadContextValue |
required | The thread and allowThreadMessagesInChannel. |
children |
ReactNode |
none | The components that read it. |
useCreateThreadContext({ allowThreadMessagesInChannel, thread }) returns a memoized value for it. Under ThreadProvider alone, inside a Channel, useThreadContext() and useMessagePaginator() return the thread's values, but useMessageComposer() still returns the channel's composer, which Thread sets in providers of its own, and nothing loads or activates the thread. Render Thread to show a thread's replies.
AlsoSentToChannelHeaderPressPayload, the argument of onAlsoSentToChannelHeaderPress, is exported from the same module: { targetedMessageId, thread? }, the reply's id and, in the channel, its thread.
Related hooks
| Hook | Returns |
|---|---|
useThreadContext() |
the values above; thread is undefined outside a Thread |
useThreadListItemContext() |
the thread of a ThreadList row, a separate context |
useMessagePaginator() |
the thread's paginator inside a Thread, the channel's outside |
useMessageComposer() |
the thread's composer inside a Thread, the channel's outside |
See useThreadContext and useMessagePaginator.