# 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,
  MessageInput,
  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 />
      <MessageInput />
    </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/v8/core-components/channel-list#onnewmessagenotification/) and `message.new` via [`onNewMessage`](/chat/docs/sdk/react-native/v8/core-components/channel-list#onnewmessage/).

</admonition>

## Context Providers

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

| Context                                                                                                                                             | Hook               |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| [`ChannelsContext`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/contexts/channelsContext/ChannelsContext.tsx) | useChannelsContext |

## Props

### `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.

<admonition type="info">

For best performance, pass a stable reference (not created inline), or memoize it.

</admonition>

| Type   |
| ------ |
| 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.

<admonition type="info">

For best performance, pass a stable reference (not created inline), or memoize it.

</admonition>

| Type   |
| ------ |
| 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.

<admonition type="info">

Unlike the **[filters](#filters)** or **[sort](#sort)** objects, changing the options object alone will not re-query the list of channels.

</admonition>

| Type   |
| ------ |
| Object |

### `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.

<admonition type="note">

`Channel` instances are not serializable, so passing them through navigation params will warn.

</admonition>

| Type               |
| ------------------ |
| `(channel) ⇒ void` |

### `additionalFlatListProps`

Additional props provided to the underlying [FlatList](https://reactnative.dev/docs/flatlist#props).

| Type   |
| ------ |
| Object |

### `loadMoreThreshold`

Sets the [`onEndReachedThreshold`](https://reactnative.dev/docs/flatlist#onendreachedthreshold). We recommend `0.1`; higher values may trigger extra `channelQuery` calls.

| Type   | Default |
| ------ | ------- |
| Number | 0.1     |

### `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.

| Type    | Default |
| ------- | ------- |
| Boolean | `false` |

### `maxUnreadCount`

Max unread badge value. Cannot exceed 255 (backend limit).

| Type   | Default |
| ------ | ------- |
| Number | 255     |

### `numberOfSkeletons`

The number of [`Skeleton`](#skeleton) items to display in the [`LoadingIndicator`](#loadingindicator).

| Type   | Default |
| ------ | ------- |
| Number | 6       |

### `onAddedToChannel`

Override the default handler for when the user is added to a channel (default adds the channel).

| Type     |
| -------- |
| Function |

| Parameter   | Description                                                                                                                               |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| setChannels | Setter function for the internal channels state                                                                                           |
| event       | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to notification.added_to_channel                               |
| options     | [ChannelListEventListenerOptions](/chat/docs/sdk/react-native/v8/core-components/channel-list#channel-list-event-listener-options) object |

### `onChannelDeleted`

Override the default handler for channel deletion (default removes the channel).

| Type     |
| -------- |
| Function |

| Parameter   | Description                                                                                   |
| ----------- | --------------------------------------------------------------------------------------------- |
| setChannels | Setter function for the internal channels state                                               |
| event       | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to channel.deleted |

### `onChannelHidden`

Override the default handler for channel hidden (default removes the channel).

| Type     |
| -------- |
| Function |

| Parameter   | Description                                                                                   |
| ----------- | --------------------------------------------------------------------------------------------- |
| setChannels | Setter function for the internal channels state                                               |
| event       | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to channel.deleted |

### `onChannelMemberUpdated`

Override the default handler for `member.updated`. Required for pinning and archiving to work.

| Type     |
| -------- |
| Function |

| Parameter        | Description                                                                                                                               |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| 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.   |
| setChannels      | Setter function for the internal channels state.                                                                                          |
| event            | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to message.new.                                                |
| options          | [ChannelListEventListenerOptions](/chat/docs/sdk/react-native/v8/core-components/channel-list#channel-list-event-listener-options) object |

### `onChannelVisible`

Override the default handler for channel visible (default adds the channel).

| Type     |
| -------- |
| Function |

| Parameter   | Description                                                                                   |
| ----------- | --------------------------------------------------------------------------------------------- |
| setChannels | Setter function for the internal channels state                                               |
| event       | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to channel.deleted |

### `onChannelTruncated`

Override the default handler for channel truncated (default reloads the list).

| Type     |
| -------- |
| Function |

| Parameter   | Description                                                                                   |
| ----------- | --------------------------------------------------------------------------------------------- |
| setChannels | Setter function for the internal channels state                                               |
| event       | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to channel.deleted |

### `onChannelUpdated`

Override the default handler for channel updated (default updates the channel `data` from the event).

| Type     |
| -------- |
| Function |

| Parameter   | Description                                                                                   |
| ----------- | --------------------------------------------------------------------------------------------- |
| setChannels | Setter function for the internal channels state                                               |
| event       | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to channel.deleted |

### `onNewMessageNotification`

Override the default handler for new message on an unwatched channel (default adds the channel).

| Type     |
| -------- |
| Function |

| Parameter   | Description                                                                                                                               |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| setChannels | Setter function for the internal channels state                                                                                           |
| event       | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to channel.deleted                                             |
| options     | [ChannelListEventListenerOptions](/chat/docs/sdk/react-native/v8/core-components/channel-list#channel-list-event-listener-options) object |

### `onNewMessage`

Override the default handler for new message on a watched channel (default moves the channel to the top).

| Type     |
| -------- |
| Function |

| Parameter        | Description                                                                                                                               |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| 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.   |
| setChannels      | Setter function for the internal channels state.                                                                                          |
| event            | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to message.new.                                                |
| options          | [ChannelListEventListenerOptions](/chat/docs/sdk/react-native/v8/core-components/channel-list#channel-list-event-listener-options) object |

### `onRemovedFromChannel`

Override the default handler for when the user is removed from a channel (default removes the channel).

| Type     |
| -------- |
| Function |

| Parameter   | Description                                                                                    |
| ----------- | ---------------------------------------------------------------------------------------------- |
| setChannels | Setter function for the internal channels state.                                               |
| event       | [Event Object](/chat/docs/react/event_object/#event-object/) corresponding to channel.deleted. |

### `setFlatlistRef`

Callback function to access the underlying [FlatList](https://reactnative.dev/docs/flatlist) ref.

| Type           |
| -------------- |
| `(ref) ⇒ void` |

### `queryChannelsOverride`

A function that overrides the `ChannelManager` `queryChannels` method (`StreamChat.queryChannels`). Use it to query specific `cid`s while still paginating (not possible via normal `filters`). Rules/assumptions:

- `StreamChat.queryChannels` must be called inside `queryChannelsOverride` (it updates important client state)
- The return type has to be `Channel[]` (which is the return type of `StreamChat.queryChannels`)
- `limit` and `offset` must still be respected so `ChannelManager` can paginate correctly

| Type                       |
| -------------------------- |
| `QueryChannelsRequestType` |

<admonition type="note">

Available since version `8.2.0`.

`filters` and `sort` should still be stable/memoized. Do not change `filters` to pass different `cid`s; handle that inside `queryChannelsOverride` based on pagination params from `ChannelManager`.

</admonition>

Example override:

```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 Props

### `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).

| Type          | Default Value                                                                                                                                                           |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`EmptyStateIndicator`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/Indicators/EmptyStateIndicator.tsx) |

### `FooterLoadingIndicator`

Rendered when [`loadingNextPage` from `ChannelsContext`](https://github.com/GetStream/stream-chat-react-native/v8/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).

| Type          | Default Value                                                                                                                                                                                     |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelListFooterLoadingIndicator`](https://github.com/GetStream/stream-chat-react-native/v8/blob/main/package/src/components/ChannelList/ChannelListFooterLoadingIndicator.tsx) |

### `HeaderErrorIndicator`

Rendered when [`error` from `ChannelsContext`](/chat/docs/sdk/react-native/v8/contexts/channels-context/#error/) is true.

| Type          | Default                                                                                                                                                                                       |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelListHeaderErrorIndicator`](https://github.com/GetStream/stream-chat-react-native/v8/blob/main/package/src/components/ChannelList/ChannelListHeaderErrorIndicator.tsx) |

### `HeaderNetworkDownIndicator`

Rendered when [`isOnline` from `ChatContext`](/chat/docs/sdk/react-native/v8/contexts/chat-context/#isonline/) is false.

| Type          | Default                                                                                                                                                                                                   |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelListHeaderNetworkDownIndicator`](https://github.com/GetStream/stream-chat-react-native/v8/blob/main/package/src/components/ChannelList/ChannelListHeaderNetworkDownIndicator.tsx) |

### `List`

Component to render the list of channels.

| Type          | Default                                                                                                                                                                    |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelListMessenger`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/ChannelList/ChannelListMessenger.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).

| Type                          |
| ----------------------------- |
| `ComponentType` \|`undefined` |

### `LoadingErrorIndicator`

Rendered when [`error` from `ChannelsContext`](/chat/docs/sdk/react-native/v8/contexts/channels-context/#error/) is true, and the channel list is empty and not loading.

| Type          | Default                                                                                                                                                                  |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ComponentType | `undefined` \| [`LoadingErrorIndicator`](https://github.com/GetStream/stream-chat-react-native/v8/blob/main/package/src/components/Indicators/LoadingErrorIndicator.tsx) |

### `LoadingIndicator`

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).

| Type          | Default                                                                                                                                                                               |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelListLoadingIndicator`](https://github.com/GetStream/stream-chat-react-native/v8/blob/main/package/src/components/ChannelList/ChannelListLoadingIndicator.tsx) |

### `Preview`

List item rendered by the underlying [`FlatList`](https://reactnative.dev/docs/flatlist).

| Type          | Default                                                                                                                                                                             |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelPreviewMessenger`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx) |

### `PreviewAvatar`

Avatar component rendered within [`Preview`](#preview).

| Type          | Default                                                                                                                                                         |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelAvatar`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/ChannelPreview/ChannelAvatar.tsx) |

### **`PreviewMessage`**

Message component rendered within [`Preview`](#preview).

| Type          | Default                                                                                                                                                                         |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelPreviewMessage`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/ChannelPreview/ChannelPreviewMessage.tsx) |

### `PreviewMutedStatus`

Channel muted status component rendered within [`Preview`](#preview).

| Type          | Default                                                                                                                                                                                 |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelPreviewMutedStatus`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/ChannelPreview/ChannelPreviewMutedStatus.tsx) |

### `PreviewStatus`

Status component rendered within [`Preview`](#preview).

| Type          | Default                                                                                                                                                                       |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelPreviewStatus`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/ChannelPreview/ChannelPreviewStatus.tsx) |

### `PreviewTitle`

Title component rendered within [`Preview`](#preview).

| Type          | Default                                                                                                                                                                     |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelPreviewTitle`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/ChannelPreview/ChannelPreviewTitle.tsx) |

### `PreviewUnreadCount`

Unread count component rendered within [`Preview`](#preview).

| Type          | Default                                                                                                                                                                                 |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`ChannelPreviewUnreadCount`](https://github.com/GetStream/stream-chat-react-native/v8/blob/develop/package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx) |

### `Skeleton`

Row item rendered in the [`LoadingIndicator`](#loadingindicator).

| Type          | Default                                                                                                                                         |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | `undefined` \| [`Skeleton`](https://github.com/GetStream/stream-chat-react-native/v8/blob/main/package/src/components/ChannelList/Skeleton.tsx) |

## Channel List Event Listener Options

### `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.

| Type   |
| ------ |
| 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.

| Type   |
| ------ |
| Object |


---

This page was last updated at 2026-04-17T17:33:44.807Z.

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