ChannelList
The ChannelList
component queries an array of channel
objects from the Stream Chat API and displays as a customizable list
in the UI. It accepts props for filters
, sort
and options
, which allows you to tailor
your request to the Query Channels API. The
response array from this API is then rendered in a list and loaded into the DOM.
const channels = await client.queryChannels(filters, sort, options);
The ChannelList
component also comes pre-built with navigation functionality. The click of a list item sets the active
channel
object and loads the Channel
component.
#
Basic UsageThe ChannelList
does not have any required props, but in order to refine channel query results we recommend providing
values for filters
, sort
and options
.
caution
By default when channels query does not have any filter it will match all the channels in your application. While this might be convenient during the development, you most likely want to have at least some basic filtering.
At a minimum, the filter should include {members: { $in: [userID] }}
.
const filters = { members: { $in: [ 'jimmy', 'buffet' ] } }
const sort = { last_message_at: -1 };
const options = { limit: 10 }
<Chat client={client}>
<ChannelList filters={filters} sort={sort} options={options} />
<Channel>
<MessageList />
<MessageInput />
</Channel>
</Chat>
#
UI CustomizationChannelList
UI is determined by two of its props, List
and Preview
. The List
prop allows you to customize the container
in which the array of channels is rendered. The Preview
prop dictates the design and click functionality of an individual
channel in the list. If not provided via props, these UI components default to
ChannelListMessenger
and ChannelPreviewMessenger
.
To customize the container and list item UI for your ChannelList
, provide custom component overrides. Your custom components
will receive the same props as the defaults.
const CustomListContainer = (props) => {
// render custom list container here
};
const CustomListItem = (props) => {
// render custom list item here
};
<Chat client={client}>
<ChannelList List={CustomListContainer} Preview={CustomListItem} />
<Channel>
<MessageList />
<MessageInput />
</Channel>
</Chat>;
In cases where the customizations provided by Preview
are not enough, e.g. grouping channels under sections based on some
dynamic channel data, the renderChannels
may be a good fit as all loaded channels are passed as an argument to the function.
const renderChannels = (loadedChannels, ChannelPreview) => {
const groups = groupBy(loadedChannels, 'some_custom_channel_data');
return renderGroups(groups); // inside renderGroups you have have headings, etc...
}
<Chat client={client}>
<ChannelList {/* other props */} renderChannels={renderChannels} />
<Channel>
<MessageList />
<MessageInput />
</Channel>
</Chat>;
#
Event ListenersIn order to handle the requisite, dynamic nature of the ChannelList
, a variety of
event listeners are added on component mount.
Many of these event listeners accept custom handler functions, allowing you to override the library's default event response behavior.
Each custom handler accepts the same function arguments. Through a combination of pulling updated data off the event object and re-setting the list state, you can customize behavior and UI.
setChannels
- state setter for thechannels
value which populates the list in the DOMevent
- event object returned from each corresponding event listener
Event Type | Default Behavior | Custom Handler |
---|---|---|
channel.deleted | Removes channel from list | onChannelDeleted |
channel.hidden | Removes channel from list | onChannelHidden |
channel.truncated | Updates the channel | onChannelTruncated |
channel.updated | Updates the channel | onChannelUpdated |
channel.visible | Adds channel to list | onChannelVisible |
connection.recovered | Forces a component render | N/A |
message.new | Moves channel to top of list | N/A |
notification.added_to_channel | Moves channel to top of list and starts watching | onAddedToChannel |
notification.message_new | Moves channel to top of list and starts watching | onMessageNew |
notification.removed_from_channel | Removes channel from list | onRemovedFromChannel |
user.presence.changed | Updates the channel | N/A |
#
Customizing Event HandlersThe event type the ChannelList
reacts to and its corresponding behavior can be overridden using the appropriate prop. Let's look at an example of customizing the ChannelList component to only display frozen channels.
const filters = {
members: { $in: ['dan'] },
frozen: true
}
<ChannelList filters={filters} />
The notification.message_new
event occurs when a message is received on a channel that is not loaded but the current user is a member of.
The default behavior when this event occurs is to query the channel the message is received on, then add the channel to the top of the list, irrespective of filters
.
Thus, if a new message appears in an unfrozen channel of which the current user is a member, it will be added to the list. This may not be the desired behavior since the list is only supposed to show frozen channels.
In this case, you can replace the default functionality by providing a custom onMessageNew
function as a prop to the ChannelList
component.
onMessageNew
receives two parameters when called, setChannels
, a setter function for the internal channels
state, and event
, the Event
object received for the notification.message_new
event.
These parameters can be used to create a function that achieves the desired custom behavior.
const filters = {
members: { $in: ['dan'] },
frozen: true,
};
const customOnMessageNew = async (setChannels, event) => {
const eventChannel = event.channel;
// If the channel isn't frozen, then don't add it to the list.
if (!eventChannel?.id || !eventChannel.frozen) return;
try {
const newChannel = client.channel(eventChannel.type, eventChannel.id);
await newChannel.watch();
setChannels((channels) => [newChannel, ...channels]);
} catch (error) {
console.log(error);
}
};
<ChannelList filters={filters} onMessageNew={customOnMessageNew} />;
Similarly, events other than notification.message_new
can be handled as per application requirements.
#
Props#
additionalChannelSearchPropsAdditional props to be passed to the underlying ChannelSearch
component.
Type |
---|
object |
#
allowNewMessagesFromUnfilteredChannelsWhen the client receives message.new
, notification.message_new
, and notification.added_to_channel
events, we automatically push
that channel to the top of the list. If the channel doesn't currently exist in the list, we grab the channel from client.activeChannels
and push it to the top of the list. You can disable this behavior by setting this prop to false, which will prevent channels not in the
list from incrementing the list.
Type | Default |
---|---|
boolean | true |
#
AvatarCustom UI component to display the user's avatar.
Type | Default |
---|---|
component | Avatar |
#
channelRenderFilterFnOptional function to filter channels prior to loading in the DOM. Do not use any complex or async logic that would delay the
loading of the ChannelList
. We recommend using a pure function with array methods like filter/sort/reduce.
Type |
---|
(channels: Channel[]) => Channel[] |
#
ChannelSearchCustom UI component to display search results.
Type | Default |
---|---|
component | ChannelSearch |
#
customActiveChannelSet a channel (with this ID) to active and force it to move to the top of the list.
Type |
---|
string |
#
EmptyStateIndicatorCustom UI component for rendering an empty list.
Type | Default |
---|---|
component | EmptyStateIndicator |
#
filtersAn object containing channel query filters, check our query parameters docs for more information.
Type |
---|
object |
#
ListCustom UI component to display the container for the queried channels.
Type | Default |
---|---|
component | ChannelListMessenger |
#
LoadingErrorIndicatorCustom UI component to display the loading error indicator.
Type | Default |
---|---|
component | ChatDown |
#
LoadingIndicatorCustom UI component to display the loading state.
Type | Default |
---|---|
component | LoadingChannels |
#
lockChannelOrderWhen true, channels won't dynamically sort by most recent message.
Type | Default |
---|---|
boolean | false |
#
onAddedToChannelFunction to override the default behavior when a user is added to a channel.
Type |
---|
function |
#
onChannelDeletedFunction to override the default behavior when a channel is deleted.
Type |
---|
function |
#
onChannelHiddenFunction to override the default behavior when a channel is hidden.
Type |
---|
function |
#
onChannelTruncatedFunction to override the default behavior when a channel is truncated.
Type |
---|
function |
#
onChannelUpdatedFunction to override the default behavior when a channel is updated.
Type |
---|
function |
#
onChannelVisibleFunction to override the default channel visible behavior.
Type |
---|
function |
#
onMessageNewFunction to override the default behavior when a message is received on a channel not being watched.
Type |
---|
function |
#
onRemovedFromChannelFunction to override the default behavior when a user gets removed from a channel.
Type |
---|
function |
#
optionsAn object containing channel query options, check our query parameters docs for more information.
Type |
---|
object |
#
PaginatorCustom UI component to handle channel pagination logic.
Type | Default |
---|---|
component | LoadMorePaginator |
#
PreviewCustom UI component to display the channel preview in the list.
Type | Default |
---|---|
component | ChannelPreviewMessenger |
#
renderChannelsFunction to override the default behavior when rendering channels, so this function is called instead of rendering the Preview directly.
Type |
---|
function |
#
sendChannelsToListIf true, sends the list's currently loaded channels to the List
component as the loadedChannels
prop.
Type | Default |
---|---|
boolean | false |
#
setActiveChannelOnMountIf true, sets the most recent channel received from the query as active on component mount. If set to false
no channel is set as active on mount.
Type | Default |
---|---|
boolean | true |
#
showChannelSearchIf true, renders the ChannelSearch
component above the List
component.
Type | Default |
---|---|
boolean | false |
#
sortAn object containing channel query sort parameters. Check our query parameters docs for more information.
Type |
---|
object |
#
watchersAn object containing query parameters for fetching channel watchers.
Type |
---|
{ limit?: number; offset?: number } |