import {
Chat,
ChatView,
ChannelList,
Channel,
ThreadList,
Thread,
useCreateChatClient,
} from "stream-chat-react";
const App = () => {
const chatClient = useCreateChatClient(/*...*/);
if (!chatClient) return null;
return (
<Chat client={chatClient}>
<ChatView>
<ChatView.Selector />
{/* Channel View */}
<ChatView.Channels>
<ChannelList />
<Channel>{/*...*/}</Channel>
</ChatView.Channels>
{/* Thread View */}
<ChatView.Threads>
<ThreadList />
<ChatView.ThreadAdapter>
<Thread />
</ChatView.ThreadAdapter>
</ChatView.Threads>
</ChatView>
</Chat>
);
};ChatView
ChatView is a component (and a set of helpers) that provides a drop-in channel view + thread view switcher. It lets users toggle views without you building that logic yourself. It includes:
ChatView- provider that stores the current viewChatView.Selector- switches the active viewChatView.Channels- renders children when view ischannelsChatView.Threads- renders children when view isthreads, and exposesThreadsViewContextfor active thread selectionChatView.ThreadAdapter- reads the active thread fromThreadsViewContextand forwards it toThreadProvider
Best Practices
- Use
ChatViewwhen you need a clear channel/thread switcher without custom state. - Keep
ChatView.Selectorvisible and accessible for quick context switching. - Use
ThreadAdapterto avoid manual thread wiring when possible. - For custom threads views, use
useActiveThreadto manage lifecycle correctly. - Keep thread view rendering lightweight to avoid expensive toggles.
Basic Usage
Custom Threads View
This section shows how to build a custom threads view using the core components and hooks.
Required Components & Hooks
These components and hooks are required for your own implementation to work properly:
ThreadListThreadListItem- provider forThreadListItemUiwith thread data; use it to wire custom click handlingThreadProvider- "adapter" for Thread component to work properly withThreadinstanceThread- renders the thread UI withMessageListandMessageInputconfigured for threadsuseActiveThread- takes your selected thread instance and handles its activity state (Thread.activate()&Thread.deactivate()) based on document focus and visibility
Building Custom Threads View
import {
ThreadList,
ThreadListItem,
ThreadProvider,
Thread,
WithComponents,
useActiveThread,
} from "stream-chat-react";
export const CustomThreadsView = () => {
const [activeThread, setActiveThread] = useState(undefined);
useActiveThread({ activeThread });
return (
<div className="custom-threads-view">
<ThreadList
virtuosoProps={{
itemContent: (_, thread) => (
<ThreadListItem
thread={thread}
threadListItemUiProps={{
"aria-selected": thread === activeThread,
onClick: () => {
setActiveThread(thread);
},
}}
/>
),
}}
/>
{activeThread && (
<ThreadProvider thread={activeThread}>
<Thread />
</ThreadProvider>
)}
</div>
);
};