# 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 `ChatView` when you want a built-in channel/thread switcher without writing custom view state.
- Keep `ChatView.Selector` visible when the thread list is part of the main navigation flow.
- Remember that `ChatView.Selector` is icon-only by default; set `iconOnly={false}` if you want labels.
- Use `ChatView.ThreadAdapter` when you want the SDK to wire the selected thread into `ThreadProvider`.
- Use `useActiveThread()` if you build a fully custom thread view outside `ChatView.ThreadAdapter`.

## Basic Usage

```tsx
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>
);
```

## Included Helpers

`ChatView` includes:

- `ChatView.Selector` for switching between views
- `ChatView.Channels` for the channel surface
- `ChatView.Threads` for the thread surface plus `ThreadsViewContext`
- `ChatView.ThreadAdapter` for forwarding the selected thread into `ThreadProvider`
- `useThreadsViewContext()` for reading or setting the active thread

## `ChatView.Selector`

`ChatView.Selector` renders channel and thread selector buttons. The default is icon-only:

```tsx
<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.

```tsx
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>
    </>
  );
};
```


---

This page was last updated at 2026-07-09T16:01:15.694Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/components/utility-components/chat-view/](https://getstream.io/chat/docs/sdk/react/components/utility-components/chat-view/).