# Providers and context hooks

Components in the UI layer don't fetch or keep chat data. They read it from objects in the state layer, and get those objects in two ways:

- **From the nearest provider above them.** `<Chat/>` provides the client, `<Channel/>` provides a channel, and `<Thread/>` provides a thread. Inside those, narrower providers provide one item: each message in a message list provides its message, a poll provides its poll, and each channel list row provides its channel.
- **As a prop.** `<ChannelList/>` renders the `ChannelPaginator` you pass it, and `<Channel/>` and `<Thread/>` take the channel and thread they provide.

Use this page to know which channel or thread a component works on, and to read the same objects in your own components.

Take this tree:

```tsx
import type {
  Channel as StreamChannel,
  Thread as StreamThread,
} from "stream-chat";
import {
  Channel,
  ChannelHeader,
  Chat,
  MessageComposer,
  MessageList,
  Thread,
  ThreadHeader,
} from "stream-chat-react";

type ConversationProps = {
  channel: StreamChannel;
  thread?: StreamThread;
};

export const Conversation = ({ channel, thread }: ConversationProps) => (
  <Chat client={client}>
    <Channel channel={channel}>
      <ChannelHeader />
      <MessageList />
      <MessageComposer />
    </Channel>
    {thread && (
      <Thread thread={thread}>
        <ThreadHeader />
        <MessageList />
        <MessageComposer />
      </Thread>
    )}
  </Chat>
);
```

The two `<MessageList/>` elements are the same component. The first renders `channel.messagePaginator`, because the nearest owner is the channel. The second renders `thread.messagePaginator`, because the nearest owner is the thread. The two `<MessageComposer/>` elements work the same way: the first writes into `channel.messageComposer`, the second into `thread.messageComposer`. No prop says which one to use.

With a layout, you don't render `<Channel/>` and `<Thread/>` yourself: `<ChannelSlot/>` and `<ThreadSlot/>` render them for the channel or thread in their slot. See [Workspace with ChatView](https://getstream.io/chat/docs/sdk/react/ui/layout/workspace-with-chatview/).

## Chat

`<Chat/>` goes around every other SDK component. It takes a connected client, such as the one `useCreateChatClient` returns (see [Quick start](https://getstream.io/chat/docs/sdk/react/getting-started/quick-start/#create-the-client)).

It provides:

| What                                                                                                                        | Read it with                                                                                                                       |
| --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| the client, its channel manager, the search controller, the users the current user has muted, and the theme and class names | `useChatContext()`                                                                                                                 |
| translations, from the `i18nInstance` you pass or a default English one                                                     | `useTranslationContext()`                                                                                                          |
| the dialog manager for modals, and the screen-reader announcer                                                              | the SDK's dialogs and components                                                                                                   |
| the display filter that decides where notifications appear                                                                  | the notification lists, see [Notifications UI](https://getstream.io/chat/docs/sdk/react/ui/components/notifications-ui/#hiding-notifications-in-lists) |
| voice recording playback, so one recording plays at a time                                                                  | the voice recording players                                                                                                        |

Every prop is on [Chat](https://getstream.io/chat/docs/sdk/react/component-reference/chat/chat/), and every field of the context on [ChatContext](https://getstream.io/chat/docs/sdk/react/component-reference/chat/chatcontext/).

While it's mounted, it also:

- starts the event subscriptions of `client.channelManager`, `client.threads`, `client.polls` and `client.reminders`, and the reminders' timers, so channel lists, the thread list, polls and reminders follow events. It stops them when it unmounts.
- publishes a notification while the connection is lost. It renders no banner for it: see [System notifications](https://getstream.io/chat/docs/sdk/react/ui/components/notifications-ui/#system-notifications).

`<Chat/>` doesn't connect the user, load channels or decide where anything opens.

### The search controller

`<Chat/>` creates a `SearchController` with a channel, a user and a message source, and the search components read it from `ChatContext`. It disposes of that controller when it unmounts.

To use other sources, create the controller yourself and pass it as `searchController`. A controller you pass is yours to manage: call `SearchController.registerSubscriptions()` when it mounts and `SearchController.dispose()` when it unmounts, as `<Chat/>` does for its own. [Choosing what to search](https://getstream.io/chat/docs/sdk/react/features/channels/search/#choosing-what-to-search) has a sample controller that searches only channels and users.

The sources and their state are explained on [Search sources](https://getstream.io/chat/docs/sdk/react/state/loading-data/search-sources/).

## Channel and Thread

`<Channel/>` binds one channel to the components inside it. It takes a `channel` and nothing else:

- **It doesn't load the channel.** Watch the channel before you pass it, for example with `Channel.watch()`, as [Show one channel](https://getstream.io/chat/docs/sdk/react/getting-started/quick-start/#show-one-channel) does. A channel from a channel list is already loaded, and the SDK's search results watch a channel before they open it.
- **It activates the channel while it's mounted.** An active channel stays loaded and is reloaded after a reconnect. See [Entity lifecycle](https://getstream.io/chat/docs/sdk/react/state/state-and-entities/entity-lifecycle/).
- **It renders the channel's container,** the `str-chat__channel` element, around its children. To fill the same place while no channel is selected, render `<ChannelPlaceholder/>`.

`<Thread/>` binds one thread. It takes a `thread` and renders no UI of its own, only its container, the `str-chat__thread` element, around its children:

- **Get the thread from the client,** with `client.threads.ensure({ channel, parentMessage })`, or from the thread list. Never construct one: a thread the client doesn't know receives no events.
- **It loads the thread while its state is stale.** A thread created from its parent message starts stale when it may have replies to load.
- **It renders nothing** until the parent message is known, and nothing when replies are turned off for the channel's type.
- **It doesn't need a `<Channel/>` around it.** Inside a `<Thread/>`, `useChannel()` returns the thread's channel.

Which object each part of a channel or thread holds is on [What channels and threads hold](https://getstream.io/chat/docs/sdk/react/state/channels-and-threads/what-channels-and-threads-hold/).

## Contexts

Your own components read the same objects through context hooks. This one sits inside a `<Channel/>` or a `<Thread/>`:

```tsx
import {
  useChannel,
  useChatContext,
  useThreadContext,
} from "stream-chat-react";

export const WhereAmI = () => {
  const { client } = useChatContext();
  const channel = useChannel();
  const thread = useThreadContext();

  return (
    <p>
      {client.userId} is in {channel.cid}
      {thread ? `, in the thread of message ${thread.id}` : ""}
    </p>
  );
};
```

| Hook                             | Returns                                                                                                                                         | Provided by                                                      | Outside its provider     |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ------------------------ |
| `useChatContext()`               | `client`, `channelManager`, `searchController`, `mutes` and more, see [ChatContext](https://getstream.io/chat/docs/sdk/react/component-reference/chat/chatcontext/) | `<Chat/>`                                                        | throws                   |
| `useChannel()`                   | the channel: the thread's channel inside a `<Thread/>`, otherwise the `<Channel/>`'s                                                            | `<Channel/>` or `<Thread/>`                                      | throws                   |
| `useThreadContext()`             | the thread                                                                                                                                      | `<Thread/>`                                                      | returns `undefined`      |
| `useMessageContext()`            | the message, its handlers (`handleDelete`, `handleReaction`, ...) and display options for one message                                           | `<Message/>`, once for each message a message list renders       | throws                   |
| `useTranslationContext()`        | `t`, `tDateTimeParser`, `userLanguage`                                                                                                          | `<Chat/>`                                                        | returns English defaults |
| `useChannelListItemContext()`    | `{ channel }`, the channel of one channel list row                                                                                              | each row a channel list renders                                  | throws                   |
| `usePollContext()`               | `{ poll }`                                                                                                                                      | `<Poll/>`, for a message that carries a poll                     | throws                   |
| `useMessageComposerController()` | the composer: the thread's inside a `<Thread/>`, otherwise the channel's, or the one a `MessageComposerControllerProvider` was given            | `<Channel/>`, `<Thread/>` or `MessageComposerControllerProvider` | throws                   |
| `useMessagePaginator()`          | the message paginator: the thread's inside a `<Thread/>`, otherwise the channel's                                                               | `<Channel/>` or `<Thread/>`                                      | throws                   |

`useMessageContext()` is how a custom message UI reads its message, because the SDK passes it no props. See [A custom MessageUI](https://getstream.io/chat/docs/sdk/react/ui/components/overriding-components/#a-custom-messageui).

### Which owner a hook reads

The context hooks find their owner from where the component sits, so the same component works in a channel and in a thread:

| Hook                             | Inside a `<Channel/>`      | Inside a `<Thread/>`      |
| -------------------------------- | -------------------------- | ------------------------- |
| `useChannel()`                   | the channel                | the thread's channel      |
| `useThreadContext()`             | `undefined`                | the thread                |
| `useMessageComposerController()` | `channel.messageComposer`  | `thread.messageComposer`  |
| `useMessagePaginator()`          | `channel.messagePaginator` | `thread.messagePaginator` |

Below a `MessageComposerControllerProvider`, `useMessageComposerController()` returns the composer that provider was given instead, for example the one editing a message inline, as in [Inline message editing](https://getstream.io/chat/docs/sdk/react/ui-cookbooks/composer/inline-message-editing/).

`useMessagePaginator()` picks the message paginator the way the SDK's own message lists do: the thread's when there is one, otherwise the channel's.

The objects these hooks return hold their data in stores. Rendering from a store, and the rules that keep it current, are on [Reading state in components](https://getstream.io/chat/docs/sdk/react/ui/reading-state-in-components/).

## Pitfalls

- **Passing a channel that was never watched.** `<Channel/>` renders what the channel holds and doesn't load it. Watch it first.
- **Reading the channel's composer or messages inside a thread.** Inside a `<Thread/>`, `useChannel()` returns the thread's channel, so `channel.messageComposer` and `channel.messagePaginator` are the channel's, not the thread's. Read the composer with `useMessageComposerController()`, the message paginator with `useMessagePaginator()`, and the thread with `useThreadContext()`, so the component works in both places.
- **Calling a throwing hook outside its provider.** `useChannel()` throws outside a `<Channel/>` or a `<Thread/>`, and so do the hooks built on it, such as `useMessageComposerController()` and `useChannelCapabilities()`. `useChatContext()` throws outside `<Chat/>`. Render the component inside the provider. In a channel list row, read the row's channel with `useChannelListItemContext()`.
- **Creating a thread with `new Thread`.** Use `client.threads.ensure()`, so the thread is the one instance the client keeps up to date.

## Used in

Every page that renders state, including:

- [Channel UI](https://getstream.io/chat/docs/sdk/react/ui/components/channel-ui/)
- [Thread UI](https://getstream.io/chat/docs/sdk/react/ui/components/thread-ui/)
- [Thread list UI](https://getstream.io/chat/docs/sdk/react/ui/components/thread-list-ui/)
- [Message list UI](https://getstream.io/chat/docs/sdk/react/ui/components/message-list-ui/)

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/ui/providers-and-context-hooks/](https://getstream.io/chat/docs/sdk/react/ui/providers-and-context-hooks/).