ChannelListContext
ChannelListContext makes a channel list's ChannelPaginator reachable from the components inside the list. ChannelLists provides it, and so does ChannelNavigation, which renders ChannelLists. A ChannelList you render yourself doesn't provide it: wrap it in ChannelListContextProvider. The paginator is explained on Channel list paginators.
Basic usage
Read the context with useChannelListContext(). It returns {} outside a list, so check the paginator before you use it:
import type { ChannelPaginator } from "stream-chat";
import {
useChannelListContext,
useChannelPaginatorState,
} from "stream-chat-react";
const LoadedCount = ({ paginator }: { paginator: ChannelPaginator }) => {
const { channels } = useChannelPaginatorState(paginator);
return <span>{channels?.length ?? 0} channels loaded</span>;
};
export const ListStatus = () => {
const { paginator } = useChannelListContext();
if (!paginator) return null;
return <LoadedCount paginator={paginator} />;
};The context holds the paginator, not its channels. A component re-renders when the context gives it another paginator, not when the list changes: read the channels with useChannelPaginatorState.
Values
| Value | Type | Description |
|---|---|---|
paginator |
ChannelPaginator | undefined |
The list's paginator. Under ChannelLists, the first paginator registered on client.channelManager. undefined outside a list. |
ChannelLists provides one context around all the lists it renders, so a component in the second list also gets the first list's paginator. To give each list its own, wrap each one in ChannelListContextProvider, as in the example below.
With the paginator, a component can:
- read the loaded channels with
useChannelPaginatorState(paginator); - load the next page with
ChannelPaginator.toTail(); - reload the list from the first page with
ChannelPaginator.reload().
The SDK reads the context too: a notification published from inside a list, such as one from a row action, is tagged for the channel-list panel, which ChannelNavigation renders below its lists. See Routing notifications.
Customizing the list UI
The list's override keys, such as ListItem, ChannelListItemUI and EmptyListIndicator, are on ChannelList and Channel Preview. A replacement registered under one of them renders inside the list, so it can read this context.
Examples
Give a list its own context
This sidebar renders two lists, each with a header that counts its own channels:
import type { ChannelPaginator } from "stream-chat";
import {
ChannelList,
ChannelListContextProvider,
useChannelListContext,
useChannelPaginatorState,
} from "stream-chat-react";
const LoadedCount = ({ paginator }: { paginator: ChannelPaginator }) => {
const { channels } = useChannelPaginatorState(paginator);
return <span>({channels?.length ?? 0})</span>;
};
const ListHeader = ({ title }: { title: string }) => {
const { paginator } = useChannelListContext();
return (
<h2>
{title} {paginator && <LoadedCount paginator={paginator} />}
</h2>
);
};
const Section = ({
paginator,
title,
}: {
paginator: ChannelPaginator;
title: string;
}) => (
<ChannelListContextProvider value={{ paginator }}>
<ListHeader title={title} />
<ChannelList paginator={paginator} />
</ChannelListContextProvider>
);
export const Sidebar = ({
archive,
inbox,
}: {
archive: ChannelPaginator;
inbox: ChannelPaginator;
}) => (
<div className="sidebar">
<Section paginator={inbox} title="Inbox" />
<Section paginator={archive} title="Archive" />
</div>
);Both paginators have to be registered on client.channelManager, as ChannelList shows.
Hooks
useChannelListContextreturns this context.useChannelPaginatorStatereads a paginator's channels and loading state.