Skip to main content
Version: v11

ChannelListContext

The context value is provided by ChannelListContextProvider which wraps the contents rendered by ChannelList. It exposes API that the default and custom components rendered by ChannelList can take advantage of. The components that can consume the context are customizable via ChannelListProps:

  • Avatar - component used to display channel image
  • ChannelSearch - renders channel search input and results
  • EmptyStateIndicator - rendered when the channels query returns and empty array
  • LoadingErrorIndicator - rendered when the channels query fails
  • LoadingIndicator- rendered during the channels query
  • List - component rendering LoadingErrorIndicator, LoadingIndicator, EmptyStateIndicator, Paginator and the list of channel Preview components
  • Paginator - takes care of requesting to load more channels into the list (pagination)
  • Preview - renders the information of a channel in the channel list

Basic Usage

Access the API from context with our custom hook:

import { useChannelListContext } from 'stream-chat-react';

export const CustomComponent = () => {
const { channels, setChannels } = useChannelListContext();
// component logic ...
return(
{/* rendered elements */}
);
}

Value

channels

State representing the array of loaded channels. Channels query is executed by default only within the ChannelList component in the SDK.

Type
Channel[]

setChannels

Sets the list of Channel objects to be rendered by ChannelList component. One have to be careful, when to call setChannels as the first channels query executed by the ChannelList overrides the whole channels state. In that case it is better to subscribe to client event channels.queried and only then set the channels. In the following example, we have a component that sets the active channel based on the id in the URL. It waits until the first channels page is loaded, and then it sets the active channel. If the channel is not present on the first page, it performs additional API request with getChannel():

import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { ChannelList, ChannelListMessenger, ChannelListMessengerProps, getChannel, useChannelListContext, useChatContext } from 'stream-chat-react';

const DEFAULT_CHANNEL_ID = 'general';
const DEFAULT_CHANNEL_TYPE = 'messaging';

const List = (props: ChannelListMessengerProps) => {
const { channelId } = useParams();
const navigate = useNavigate();
const { client, channel, setActiveChannel } = useChatContext();
const { setChannels } = useChannelListContext();

useEffect(() => {
if (!channelId) return navigate(`/${DEFAULT_CHANNEL_ID}`);

if (channel?.id === channelId || !client) return;

let subscription: { unsubscribe: () => void } | undefined;
if(!channel?.id || channel?.id !== channelId) {
subscription = client.on('channels.queried', (event: Event) => {
const loadedChannelData = event.queriedChannels?.channels.find((response) => response.channel.id === channelId);

if (loadedChannelData) {
setActiveChannel(client.channel( DEFAULT_CHANNEL_TYPE, channelId));
subscription?.unsubscribe();
return;
}

return getChannel({client, id: channelId, type: DEFAULT_CHANNEL_TYPE}).then((newActiveChannel) => {
setActiveChannel(newActiveChannel);
setChannels((channels) => {
return ([newActiveChannel, ...channels.filter((ch) => ch.data?.cid !== newActiveChannel.data?.cid)]);
});
});
});
}

return () => {
subscription?.unsubscribe();
};
}, [channel?.id, channelId, setChannels, client, navigate, setActiveChannel]);

return <ChannelListMessenger {...props}/>;
};



const Sidebar = () => {
return (
// ...
<ChannelList
{/* some props */}
{/* setting active channel will be performed inside the custom List component */}
setActiveChannelOnMount={false}
List={List}
{/* some props */}
/>
// ...
}
Type
Dispatch<SetStateAction<Channel[]>>

Did you find this page helpful?