import {
Channel,
ChannelList,
Chat,
ChatView,
Thread,
ThreadList,
} from "stream-chat-react";
const App = () => (
<Chat client={client}>
<ChatView>
<ChatView.Selector iconOnly={false} />
<ChatView.Channels>
<ChannelList />
<Channel>{/* ... */}</Channel>
</ChatView.Channels>
<ChatView.Threads>
<ThreadList />
<ChatView.ThreadAdapter>
<Thread />
</ChatView.ThreadAdapter>
</ChatView.Threads>
</ChatView>
</Chat>
);ChatView
ChatView provides a ready-made channel/thread view switcher. It keeps the active view in context and ships with a selector plus helpers for thread selection.
Best Practices
- Use
ChatViewwhen you want a built-in channel/thread switcher without writing custom view state. - Keep
ChatView.Selectorvisible when the thread list is part of the main navigation flow. - Remember that
ChatView.Selectoris icon-only by default; seticonOnly={false}if you want labels. - Use
ChatView.ThreadAdapterwhen you want the SDK to wire the selected thread intoThreadProvider. - Use
useActiveThread()if you build a fully custom thread view outsideChatView.ThreadAdapter.
Basic Usage
Included Helpers
ChatView includes:
ChatView.Selectorfor switching between viewsChatView.Channelsfor the channel surfaceChatView.Threadsfor the thread surface plusThreadsViewContextChatView.ThreadAdapterfor forwarding the selected thread intoThreadProvideruseThreadsViewContext()for reading or setting the active thread
ChatView.Selector
ChatView.Selector renders channel and thread selector buttons. The default is icon-only:
<ChatView.Selector iconOnly={false} />If you want to customize the selector, pass a custom itemSet.
ChatView.ThreadAdapter
ChatView.ThreadAdapter reads the active thread from ThreadsViewContext, activates it with useActiveThread(), and wraps its children in ThreadProvider.
When the thread manager is ready and no thread is selected, the adapter renders the configured EmptyStateIndicator instead of an empty panel.
If you want to keep the older blank panel behavior, either provide EmptyStateIndicator={() => null} through WithComponents or bypass ChatView.ThreadAdapter and wire ThreadProvider manually with useThreadsViewContext().
Custom Threads View
If you need to customize the threads surface, ThreadList, ThreadListItem, ThreadProvider, Thread, and useActiveThread() are the core building blocks.
import {
ChatView,
Thread,
ThreadList,
ThreadListItem,
useThreadsViewContext,
} from "stream-chat-react";
const CustomThreadsPane = () => {
const { activeThread, setActiveThread } = useThreadsViewContext();
return (
<>
<ThreadList
virtuosoProps={{
itemContent: (_, thread) => (
<ThreadListItem
thread={thread}
threadListItemUIProps={{
"aria-pressed": activeThread === thread,
onClick: () => setActiveThread(thread),
}}
/>
),
}}
/>
<ChatView.ThreadAdapter>
<Thread />
</ChatView.ThreadAdapter>
</>
);
};