Info:
This is release candidate documentation for Stream Chat React SDK v15. For the latest stable version, see the latest version (v14).

Channel

Channel binds one channel to the components inside it. It activates the channel while it's mounted, renders the channel's container around its children, and stops the channel's audio players when the channel changes. It doesn't load the channel. Channel UI explains what it does, and Reading state in components how its children read the channel's state.

Best practices

  • Pass a channel that is already watched, for example with Channel.watch(). A channel from a channel list is loaded already, and the SDK's search results watch the channel they open.
  • With ChatView, let ChannelSlot render Channel for the channel in its slot. See Workspace with ChatView.
  • Read the channel in its children with useChannel(), and its state with useStateStore, rather than passing them down as props.
  • Channel takes no component props. Replace the parts inside it with WithComponents, or by rendering different children.
  • While no channel is selected, render ChannelPlaceholder in its place.

Basic usage

import {
  Channel,
  ChannelHeader,
  MessageComposer,
  MessageList,
} from "stream-chat-react";

export const ChannelPanel = () => (
  <Channel channel={channel}>
    <ChannelHeader />
    <MessageList />
    <MessageComposer />
  </Channel>
);

MessageList renders channel.messagePaginator, and MessageComposer writes into channel.messageComposer. A component of your own reads the same channel:

import type { ChannelStateData } from "stream-chat";
import { useChannel, useStateStore } from "stream-chat-react";

const frozenSelector = ({ data }: ChannelStateData) => ({
  frozen: data?.frozen,
});

export const FrozenBanner = () => {
  const channel = useChannel();
  const { frozen } = useStateStore(channel.state, frozenSelector);

  if (!frozen) return null;

  return <div className="frozen-banner">This channel is read-only.</div>;
};

Props

Prop Type Default Description
channel Channel from stream-chat required The channel to bind. Watch it before you pass it. Channel activates it while mounted, so it stays loaded and is reloaded after a reconnect; see Entity lifecycle.

Channel takes nothing else. The props it took in v14 are listed in Upgrade to v15.

ChannelPlaceholder takes the props of a div. It renders the same container as Channel, with the classes str-chat, the theme classes and str-chat__channel, but with no channel bound. Its className is added to those classes.

Examples

Watch the channel before passing it

import { useEffect, useState } from "react";
import type { Channel as StreamChannel } from "stream-chat";
import {
  Channel,
  ChannelHeader,
  MessageComposer,
  MessageList,
  useChatContext,
} from "stream-chat-react";

export const SupportChannel = ({ channelId }: { channelId: string }) => {
  const { client } = useChatContext();
  const [channel, setChannel] = useState<StreamChannel>();

  useEffect(() => {
    let cancelled = false;

    client
      .channel("messaging", channelId)
      .watch()
      .then((watchedChannel) => {
        if (!cancelled) setChannel(watchedChannel);
      })
      .catch((error) => console.error("Could not watch the channel", error));

    return () => {
      cancelled = true;
    };
  }, [channelId, client]);

  if (!channel) return <div>Loading the channel...</div>;

  return (
    <Channel channel={channel}>
      <ChannelHeader />
      <MessageList />
      <MessageComposer />
    </Channel>
  );
};

Channel.watch() resolves with the channel instance to use from then on. Loading and error states are yours to render: Channel has no query to report on.

Render something while no channel is selected

import type { Channel as StreamChannel } from "stream-chat";
import {
  Channel,
  ChannelHeader,
  ChannelPlaceholder,
  MessageComposer,
  MessageList,
} from "stream-chat-react";

export const ChannelArea = ({ channel }: { channel?: StreamChannel }) => {
  if (!channel) {
    return (
      <ChannelPlaceholder>Pick a channel to start chatting.</ChannelPlaceholder>
    );
  }

  return (
    <Channel channel={channel}>
      <ChannelHeader />
      <MessageList />
      <MessageComposer />
    </Channel>
  );
};
Hook Returns
useChannel() the channel: the thread's channel inside a Thread, otherwise the Channel's. Throws outside both
useChannelInstanceContext() { channel } inside a Channel, {} outside
useMessageComposerController() the composer of the channel, or of the thread inside a Thread
useStateStore(store, selector) a selection of a store, such as channel.state, that re-renders the component when it changes

Reading state in components explains which owner each hook reads, and Channel and thread hooks lists the hooks for channel state.