# ChannelList

`ChannelList` displays channels using React Native's [`FlatList`](https://reactnative.dev/docs/flatlist).

`ChannelList` fetches channels via the [client's query channels function](/chat/docs/javascript/query-channels/). Pass [`filters`](#filters), [`sort`](#sort), and [`options`](#options) via props.

<admonition type="note">

Use [`onSelect`](#onselect) to handle navigation when a user taps a channel.

</admonition>

## Best Practices

- Memoize `filters` and `sort` to avoid unnecessary re-queries.
- Keep `onSelect` lightweight and handle navigation outside of render.
- Handle `notification.message_new`/`message.new` if you need strict filtering on real-time updates.
- Avoid passing `Channel` instances through navigation params; store them in state instead.
- Use sensible `loadMoreThreshold` values to reduce extra queries.

## General Usage

`ChannelList` renders channels in a [FlatList](https://reactnative.dev/docs/flatlist).

> Note: Define the component within `OverlayProvider` and `Chat` so the required [contexts](https://www.notion.so/Contexts-6bdf5dd1346e433db4407131018b05b5?pvs=21) are available.

```tsx {11,12,13,14,15,16}
import { StreamChat } from 'stream-chat';
import { ChannelList, Chat, OverlayProvider } from 'stream-chat-react-native';

const client = StreamChat.getInstance('api_key');
const filters = { members: { $in: [ 'vishal', 'lucas', 'neil' ] } };
const sort = { last_updated: -1 };
const options = { limit: 20, messages_limit: 30 };

export const App = () => <OverlayProvider>
    <Chat client={client}>
      <ChannelList
        filters={filters}
        sort={sort}
        options={options}
        onSelect={(channel) => /** navigate to channel screen */ }
      />
    </Chat>
  </OverlayProvider>;
```

### Complete navigation example

Here's a practical example showing how to integrate `ChannelList` with React Navigation:

```tsx
import React, { useMemo, useState, useEffect } from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import {
  Chat,
  OverlayProvider,
  ChannelList,
  Channel,
  MessageList,
  MessageComposer,
  useCreateChatClient,
  useChatContext,
} from "stream-chat-react-native";

const Stack = createStackNavigator();

const ChannelListScreen = ({ navigation }) => {
  // Memoize filters and sort to prevent unnecessary re-renders
  const filters = useMemo(
    () => ({ members: { $in: ["user-id"] }, type: "messaging" }),
    [],
  );
  const sort = useMemo(() => [{ last_message_at: -1 }], []);

  return (
    <ChannelList
      filters={filters}
      sort={sort}
      onSelect={(channel) => {
        // Navigate to the channel screen
        // Note: Passing the channel CID, not the channel object
        navigation.navigate("Channel", { channelId: channel.cid });
      }}
    />
  );
};

const ChannelScreen = ({ route }) => {
  const { channelId } = route.params;
  const [channel, setChannel] = useState();
  const { client } = useChatContext();

  useEffect(() => {
    // Extract channel type and ID from CID (format: "type:id")
    const [type, id] = channelId.split(":");
    const channelInstance = client.channel(type, id);
    setChannel(channelInstance);
  }, [channelId, client]);

  if (!channel) return null;

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

export const App = () => {
  const chatClient = useCreateChatClient({
    apiKey: "YOUR_API_KEY",
    userData: { id: "user-id", name: "User Name" },
    tokenOrProvider: "YOUR_TOKEN",
  });

  if (!chatClient) return null;

  return (
    <OverlayProvider>
      <Chat client={chatClient}>
        <NavigationContainer>
          <Stack.Navigator>
            <Stack.Screen name="Channels" component={ChannelListScreen} />
            <Stack.Screen name="Channel" component={ChannelScreen} />
          </Stack.Navigator>
        </NavigationContainer>
      </Chat>
    </OverlayProvider>
  );
};
```

<admonition type="tip">

When using navigation, pass the channel CID (e.g., `"messaging:channel-id"`) instead of the channel object, since `Channel` instances are not serializable and will cause React Navigation warnings.

</admonition>

<admonition type="note">

When channels are added via events, filters are not applied (filters can be complex and aren't re-evaluated client-side). If you need strict filtering, override `notification.message_new` via [`onNewMessageNotification`](/chat/docs/sdk/react-native/core-components/channel-list#onnewmessagenotification/) and `message.new` via [`onNewMessage`](/chat/docs/sdk/react-native/core-components/channel-list#onnewmessage/).

</admonition>

## Context Providers

`ChannelList` provides `ChannelsContext`, accessible via its hook.

- [`ChannelsContext`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/contexts/channelsContext/ChannelsContext.tsx) (via `useChannelsContext`) - provides channel list state and actions

## Props

| Prop                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                           | Type                                 |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `filters`                  | Filter object passed to [query channels](/chat/docs/javascript/query-channels/). You can filter on [built-in](/chat/docs/javascript/query-channels/#common-filters-by-use-case/) and custom fields. For best performance, pass a stable reference (not created inline), or memoize it.                                                                                                                                                                | `object`                             |
| `sort`                     | Sort object passed to [query channels](/chat/docs/javascript/query-channels/). You can sort on [built-in](/chat/docs/javascript/query-channels/#query-parameters/) and custom fields. For best performance, pass a stable reference (not created inline), or memoize it.                                                                                                                                                                              | `object`                             |
| `options`                  | [Options object](/chat/docs/javascript/query-channels/#query-options/) passed internally to the [client query function](/chat/docs/javascript/query-channels/) as a parameter. Unlike `filters` or `sort`, changing the options object alone will not re-query the list of channels.                                                                                                                                                                  | `object`                             |
| `channelRenderFilterFn`    | Optional function to filter channels prior to rendering the list. Do not use any complex logic that would delay the loading of the ChannelList. We recommend using a pure function with array methods like filter/sort/reduce.                                                                                                                                                                                                                        | `(channels: Channel[]) => Channel[]` |
| `onSelect`                 | Called when a user taps a channel. Receives the [`Channel` instance](/chat/docs/javascript/creating-channels/) for that item and is often used for navigation. `Channel` instances are not serializable, so passing them through navigation params will warn.                                                                                                                                                                                         | `(channel) => void`                  |
| `additionalFlatListProps`  | Additional props provided to the underlying [FlatList](https://reactnative.dev/docs/flatlist#props).                                                                                                                                                                                                                                                                                                                                                  | `object`                             |
| `loadMoreThreshold`        | Sets the [`onEndReachedThreshold`](https://reactnative.dev/docs/flatlist#onendreachedthreshold). We recommend `0.1`; higher values may trigger extra `channelQuery` calls. Defaults to `0.1`.                                                                                                                                                                                                                                                         | `number`                             |
| `lockChannelOrder`         | Locks the order of the channels in the list so they will not dynamically reorder by most recent message when a new message is received. Defaults to `false`.                                                                                                                                                                                                                                                                                          | `boolean`                            |
| `maxUnreadCount`           | Max unread badge value. Cannot exceed 255 (backend limit). Defaults to `255`.                                                                                                                                                                                                                                                                                                                                                                         | `number`                             |
| `numberOfSkeletons`        | The number of [`Skeleton`](#skeleton) items to display in the [`ChannelListLoadingIndicator`](#channellistloadingindicator). Defaults to `8`.                                                                                                                                                                                                                                                                                                         | `number`                             |
| `onAddedToChannel`         | Override the default handler for when the user is added to a channel (default adds the channel). Receives parameters: `setChannels` (setter for internal channels state), `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for notification.added_to_channel), `options` ([ChannelListEventListenerOptions](#channel-list-event-listener-options) object).                                                                       | `function`                           |
| `onChannelDeleted`         | Override the default handler for channel deletion (default removes the channel). Receives parameters: `setChannels` (setter for internal channels state), `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for channel.deleted).                                                                                                                                                                                                 | `function`                           |
| `onChannelHidden`          | Override the default handler for channel hidden (default removes the channel). Receives parameters: `setChannels` (setter for internal channels state), `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for channel.hidden).                                                                                                                                                                                                    | `function`                           |
| `onChannelMemberUpdated`   | Override the default handler for `member.updated`. Required for pinning and archiving to work. Receives parameters: `lockChannelOrder`, `setChannels`, `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for member.updated), `options` ([ChannelListEventListenerOptions](#channel-list-event-listener-options) object).                                                                                                         | `function`                           |
| `onChannelVisible`         | Override the default handler for channel visible (default adds the channel). Receives parameters: `setChannels` (setter for internal channels state), `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for channel.visible).                                                                                                                                                                                                     | `function`                           |
| `onChannelTruncated`       | Override the default handler for channel truncated (default reloads the list). Receives parameters: `setChannels` (setter for internal channels state), `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for channel.truncated).                                                                                                                                                                                                 | `function`                           |
| `onChannelUpdated`         | Override the default handler for channel updated (default updates the channel `data` from the event). Receives parameters: `setChannels` (setter for internal channels state), `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for channel.updated).                                                                                                                                                                            | `function`                           |
| `onNewMessageNotification` | Override the default handler for new message on an unwatched channel (default adds the channel). Receives parameters: `setChannels` (setter for internal channels state), `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for notification.message_new), `options` ([ChannelListEventListenerOptions](#channel-list-event-listener-options) object).                                                                            | `function`                           |
| `onNewMessage`             | Override the default handler for new message on a watched channel (default moves the channel to the top). Receives parameters: `lockChannelOrder`, `setChannels`, `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for message.new), `options` ([ChannelListEventListenerOptions](#channel-list-event-listener-options) object).                                                                                                 | `function`                           |
| `onRemovedFromChannel`     | Override the default handler for when the user is removed from a channel (default removes the channel). Receives parameters: `setChannels` (setter for internal channels state), `event` ([Event Object](/chat/docs/react/event-object/#event-object/) for notification.removed_from_channel).                                                                                                                                                        | `function`                           |
| `setFlatListRef`           | Callback function to access the underlying [FlatList](https://reactnative.dev/docs/flatlist) ref.                                                                                                                                                                                                                                                                                                                                                     | `(ref) => void`                      |
| `getChannelActionItems`    | Optional function to customize the channel action items shown in the swipe row and the [`ChannelDetailsBottomSheet`](#channeldetailsbottomsheet). Receives the default items and channel context and returns the items to render.                                                                                                                                                                                                                     | `GetChannelActionItems`              |
| `mutedStatusPosition`      | Position of the muted status component within the [`ChannelPreview`](#channelpreview). Defaults to `inlineTitle`.                                                                                                                                                                                                                                                                                                                                     | `trailingBottom` \| `inlineTitle`    |
| `pinnedStatusPosition`     | Position of the pinned status component within the [`ChannelPreview`](#channelpreview). Defaults to `inlineTitle`.                                                                                                                                                                                                                                                                                                                                    | `trailingBottom` \| `inlineTitle`    |
| `swipeActionsEnabled`      | If true, the user can swipe to perform actions on a channel. Defaults to `true`.                                                                                                                                                                                                                                                                                                                                                                      | `boolean`                            |
| `queryChannelsOverride`    | A function that overrides the `ChannelManager` `queryChannels` method (`StreamChat.queryChannels`). Use it to query specific `cid`s while still paginating. `StreamChat.queryChannels` must be called inside, the return type must be `Channel[]`, and `limit`/`offset` must be respected for pagination. Available since version `8.2.0`. `filters` and `sort` should still be stable/memoized. See [example below](#querychannelsoverride-example). | `QueryChannelsRequestType`           |

## Examples

### `queryChannelsOverride` example

```ts
const cids = Array.from({ length: 25 }, (_, i) => (i + 1).toString());

const queryChannelsOverride = (filters, sort, options, ...restParams) => {
  const { limit, offset } = options;

  const cidWindow = cids.slice(offset, offset + limit);
  const newFilters = { ...filters, cid: { $in: cidWindow } };

  return chatClient.queryChannels(newFilters, sort, options, ...restParams);
};
```

Given this `ChannelList` configuration:

```tsx
// ... rest of the component
const filters = useMemo(() => ({}), []);
const options = useMemo(() => ({ offset: 0, limit: 10 }), []);
return <ChannelList filters={stableFilters} options={options} />;
```

Pagination works as follows:

1. On the first page, 10 items will be loaded, which will be the first 10 `cid`s
2. On the second page, `queryChannelsOverride` will be invoked with `offset: 10` and `limit: 10`, so `cid`s `10` through `19` will be loaded
3. On the last page, `queryChannelsOverride` will be invoked with `offset: 10` and `limit: 10`, and so our implementation will return the last 5 `cid`s (and the `ChannelManager` will at this point determine there are no pages left)

## UI Component Overrides

The UI components used by `ChannelList` can be customized via `WithComponents`. Wrap `ChannelList` (or any ancestor) with `WithComponents` and pass the components you want to override.

```tsx
import { ChannelList, WithComponents } from "stream-chat-react-native";

<WithComponents
  overrides={{
    ChannelPreview: CustomPreview,
    EmptyStateIndicator: CustomEmpty,
  }}
>
  <ChannelList filters={filters} sort={sort} />
</WithComponents>;
```

The following components can be overridden:

| Component                               | Description                                                                                                                                                                                                                                                                                                                                                                | Type                           | Default                                                                                                                                                                                   |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `EmptyStateIndicator`                   | Rendered when the channel list is empty and not loading via the [`ListEmptyComponent`](https://reactnative.dev/docs/flatlist#listemptycomponent) prop on the [`FlatList`](https://reactnative.dev/docs/flatlist).                                                                                                                                                          | ComponentType                  | [`EmptyStateIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/Indicators/EmptyStateIndicator.tsx)                                     |
| `ChannelListFooterLoadingIndicator`     | Rendered when [`loadingNextPage` from `ChannelsContext`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/contexts/channelsContext/ChannelsContext.tsx/#loadingnextpage) is true via the [`ListFooterComponent`](https://reactnative.dev/docs/flatlist#listfootercomponent) prop on the [`FlatList`](https://reactnative.dev/docs/flatlist). | ComponentType                  | [`ChannelListFooterLoadingIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelList/ChannelListFooterLoadingIndicator.tsx)           |
| `ChannelListHeaderErrorIndicator`       | Rendered when [`error` from `ChannelsContext`](/chat/docs/sdk/react-native/contexts/channels-context/#error/) is true.                                                                                                                                                                                                                                                     | ComponentType                  | [`ChannelListHeaderErrorIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelList/ChannelListHeaderErrorIndicator.tsx)               |
| `ChannelListHeaderNetworkDownIndicator` | Rendered when [`isOnline` from `ChatContext`](/chat/docs/sdk/react-native/contexts/chat-context/#isonline/) is false.                                                                                                                                                                                                                                                      | ComponentType                  | [`ChannelListHeaderNetworkDownIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelList/ChannelListHeaderNetworkDownIndicator.tsx)   |
| `ListHeaderComponent`                   | Rendered when provided if the channel list is not empty via the [`ListHeaderComponent`](https://reactnative.dev/docs/flatlist#listheadercomponent) prop on the [`FlatList`](https://reactnative.dev/docs/flatlist).                                                                                                                                                        | `ComponentType` \| `undefined` | -                                                                                                                                                                                         |
| `LoadingErrorIndicator`                 | Rendered when [`error` from `ChannelsContext`](/chat/docs/sdk/react-native/contexts/channels-context/#error/) is true, and the channel list is empty and not loading.                                                                                                                                                                                                      | ComponentType                  | [`LoadingErrorIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Indicators/LoadingErrorIndicator.tsx)                                    |
| `ChannelListLoadingIndicator`           | Rendered when the channel list is empty and loading via the [ListEmptyComponent](https://reactnative.dev/docs/flatlist#listemptycomponent) prop on the [FlatList](https://reactnative.dev/docs/flatlist).                                                                                                                                                                  | ComponentType                  | [`ChannelListLoadingIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelList/ChannelListLoadingIndicator.tsx)                       |
| `ChannelPreview`                        | List item rendered by the underlying [`FlatList`](https://reactnative.dev/docs/flatlist).                                                                                                                                                                                                                                                                                  | ComponentType                  | [`ChannelPreviewView`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelPreviewView.tsx)                                   |
| `ChannelPreviewAvatar`                  | Avatar component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                                      | ComponentType                  | [`ChannelAvatar`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelAvatar.tsx)                                             |
| `ChannelPreviewMessage`                 | Message component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                                     | ComponentType                  | [`ChannelPreviewMessage`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx)                             |
| `ChannelPreviewMutedStatus`             | Channel muted status component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                        | ComponentType                  | [`ChannelPreviewMutedStatus`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelPreviewMutedStatus.tsx)                     |
| `ChannelPreviewPinnedStatus`            | Channel pinned status component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                       | ComponentType                  | [`ChannelPreviewPinnedStatus`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelPreviewPinnedStatus.tsx)                   |
| `ChannelPreviewStatus`                  | Status component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                                      | ComponentType                  | [`ChannelPreviewStatus`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelPreviewStatus.tsx)                               |
| `ChannelPreviewTitle`                   | Title component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                                       | ComponentType                  | [`ChannelPreviewTitle`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx)                                 |
| `ChannelPreviewUnreadCount`             | Unread count component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                                | ComponentType                  | [`ChannelPreviewUnreadCount`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx)                     |
| `ChannelPreviewTypingIndicator`         | Typing indicator component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                            | ComponentType                  | [`ChannelPreviewTypingIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelPreviewTypingIndicator.tsx)             |
| `ChannelPreviewMessageDeliveryStatus`   | Message delivery status component rendered within [`ChannelPreview`](#channelpreview).                                                                                                                                                                                                                                                                                     | ComponentType                  | [`ChannelPreviewMessageDeliveryStatus`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.tsx) |
| `ChannelDetailsBottomSheet`             | Channel details bottom sheet component that triggers when a user swipes a channel and selects the options menu. Make sure you have `swipeActionsEnabled` set to `true` to use this component.                                                                                                                                                                              | ComponentType                  | [`ChannelDetailsBottomSheet`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/components/ChannelPreview/ChannelDetailsBottomSheet.tsx)                     |
| `Skeleton`                              | Row item rendered in the [`ChannelListLoadingIndicator`](#channellistloadingindicator).                                                                                                                                                                                                                                                                                    | ComponentType                  | [`Skeleton`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ChannelList/Skeleton.tsx)                                                             |

## Channel List Event Listener Options

| Prop      | Description                                                                                                                                                                                                                                                   | Type     |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `filters` | Filter object passed internally to the [client query function](/chat/docs/javascript/query-channels/) as a parameter. You can filter a query on [built-in](/chat/docs/javascript/query-channels/#common-filters-by-use-case/) and custom fields on a Channel. | `object` |
| `sort`    | Sort object passed internally to the [client query function](/chat/docs/javascript/query-channels/) as a parameter. You can sort a query on [built-in](/chat/docs/javascript/query-channels/#query-parameters/) and custom fields on a Channel.               | `object` |


---

This page was last updated at 2026-07-16T09:38:20.976Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/core-components/channel-list/](https://getstream.io/chat/docs/sdk/react-native/core-components/channel-list/).