import { useChannelListContext } from 'stream-chat-react';
export const CustomComponent = () => {
const { channels, setChannels } = useChannelListContext();
// component logic ...
return(
{/* rendered elements */}
);
}
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 imageChannelSearch
- renders channel search input and resultsEmptyStateIndicator
- rendered when the channels query returns and empty arrayLoadingErrorIndicator
- rendered when the channels query failsLoadingIndicator
- rendered during the channels queryList
- component renderingLoadingErrorIndicator
,LoadingIndicator
,EmptyStateIndicator
,Paginator
and the list of channelPreview
componentsPaginator
- 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:
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[]>> |