# ThreadList

> **Info:** This is release candidate documentation for **Stream Chat React Native SDK v10**. For the latest stable version, see the [latest version (v9)](https://getstream.io/chat/docs/sdk/react-native/).

`ThreadList` lists the threads the current user takes part in. It reads `client.threads`, the thread manager, and renders a row for each thread in a React Native `FlatList`. [Thread UI](https://getstream.io/chat/docs/sdk/react-native/v10/ui/components/thread-ui/#the-thread-list) describes what it shows, and [Replies and threads](https://getstream.io/chat/docs/sdk/react-native/v10/features/messaging/replies-and-threads/#the-thread-list) how the list loads and stays current.

## Best practices

- Render it anywhere inside `Chat`. It needs no `Channel`.
- Pass the focus state of its screen as `isFocused`, such as `useIsFocused()` from React Navigation. The list keeps `client.threads` active only while it's `true`, so a hidden screen doesn't keep reloading the list.
- Render one `ThreadList` at a time. Each one deactivates `client.threads` when it unmounts or loses focus, even while another list is still on screen.
- Open the thread in `onThreadSelect`, for example by navigating to a screen that renders [`Thread`](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/thread-list/thread/) with it. Without `onThreadSelect`, tapping a row does nothing.
- Change the rows through the `ThreadListItem` override key, and keep them light: rows mount and unmount as the user scrolls.

## Basic usage

```tsx title="src/ThreadsScreen.tsx"
import { useIsFocused } from "@react-navigation/native";
import type { Thread } from "stream-chat";
import { ThreadList } from "stream-chat-react-native";

export const ThreadsScreen = ({
  openThread,
}: {
  openThread: (thread: Thread) => void;
}) => {
  const isFocused = useIsFocused();

  return <ThreadList isFocused={isFocused} onThreadSelect={openThread} />;
};
```

`openThread` gets the `Thread` instance of the row. Navigate with it, and render `<Thread thread={thread}>` on the thread's screen, as [Moving between channels, threads and messages](https://getstream.io/chat/docs/sdk/react-native/v10/ui/layout/moving-between-channels-threads-and-messages/) shows. The thread's channel is `thread.channel`.

`ThreadList` renders, from top to bottom:

- `ThreadListUnreadBanner`, while threads outside the loaded list have new replies;
- the rows, one for each thread in `client.threads.paginator`;
- `ThreadListLoadingMoreIndicator` after the last row while the next page loads, or `ThreadListEmptyPlaceholder`, "Reply to a message to start a thread", when there are no threads;
- a `NotificationList` for the list's notifications.

While the first page loads, it renders `ThreadListLoadingIndicator`, ten placeholder rows, instead of the banner and the rows. It loads the next page when the user scrolls to the end.

## UI customization

`ThreadList` reads these keys from `WithComponents`. [Thread UI](https://getstream.io/chat/docs/sdk/react-native/v10/ui/components/thread-ui/#replacing-parts) shows a replacement row.

| Override key                     | Replaces                                                                | Default                                 | Props                                                                                                                                           |
| -------------------------------- | ----------------------------------------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `ThreadListComponent`            | Everything above the notifications: the banner, the rows and the states | `DefaultThreadListComponent`            | none; reads `useThreadsContext()`                                                                                                               |
| `ThreadListItem`                 | A row                                                                   | not exported                            | none; reads `useThreadListItemContext()`. See [ThreadListItem](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/thread-list/threadlistitem/) |
| `ThreadListUnreadBanner`         | The banner that reloads the list                                        | not exported                            | none                                                                                                                                            |
| `ThreadListLoadingIndicator`     | The placeholder rows while the first page loads                         | `DefaultThreadListLoadingIndicator`     | none                                                                                                                                            |
| `ThreadListLoadingMoreIndicator` | The spinner after the last row                                          | `DefaultThreadListLoadingNextIndicator` | none                                                                                                                                            |
| `ThreadListEmptyPlaceholder`     | What shows when there are no threads                                    | `DefaultThreadListEmptyPlaceholder`     | none                                                                                                                                            |
| `NotificationList`               | The notifications shown over the list                                   | `NotificationList`                      | see [NotificationList](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/notifications/notification-list/)                                    |

The banner shows "2 new threads" while `client.threads.state` lists unseen threads, and tapping it reloads the list with `client.threads.reload()`. When the reload fails, it says so, and tapping it tries again.

## Props

| Prop                      | Type                             | Default                          | Description                                                                                                                                                                                                                                                               |
| ------------------------- | -------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `isFocused`               | `boolean`                        | `true`                           | While `true`, `client.threads` is active: it loads the first page when the list has none, and reloads the list when threads got replies while it was inactive. `false` deactivates it. The type requires the prop, though the component treats a missing value as `true`. |
| `onThreadSelect`          | `(thread: Thread) => void`       | none                             | Called with the row's thread when the user taps a row.                                                                                                                                                                                                                    |
| `additionalFlatListProps` | `Partial<FlatListProps<Thread>>` | none                             | Props for the `FlatList`. They're spread after the SDK's own, so `data`, `renderItem`, `onEndReached` and `ListEmptyComponent` replace the SDK's.                                                                                                                         |
| `notificationHostId`      | `string`                         | `"thread-list:"` and a random id | The notification host the list's notifications are routed to. Pass one to publish notifications to this list from elsewhere.                                                                                                                                              |

When the list unmounts, it deactivates `client.threads`.

## ThreadsContext

`ThreadList` provides `ThreadsContext` to everything it renders. `useThreadsContext()` reads it, and throws outside a `ThreadList`.

| Value                     | Type                             | Description                                                                                                  |
| ------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `threads`                 | `Thread[]`                       | The threads of `client.threads.paginator`, in the list's order.                                              |
| `isLoading`               | `boolean`                        | Whether the first page is loading: the paginator is loading and has no threads.                              |
| `isLoadingNext`           | `boolean`                        | Whether the next page is loading: the paginator is loading and has threads.                                  |
| `loadMore`                | `() => Promise<void>`            | Loads the next page with `client.threads.paginator.toTail()`. Does nothing while a page loads or at the end. |
| `onThreadSelect`          | `(thread: Thread) => void`       | The `ThreadList` prop. The default row calls it when tapped.                                                 |
| `isFocused`               | `boolean`                        | The `ThreadList` prop, as passed.                                                                            |
| `additionalFlatListProps` | `Partial<FlatListProps<Thread>>` | The `ThreadList` prop. The default list spreads it onto its `FlatList`.                                      |

`ThreadsContext`, `ThreadsProvider` and the `ThreadsContextValue` type are exported. A `ThreadListComponent` of your own reads the threads and the loading states from it:

```tsx title="src/CompactThreadList.tsx"
import { FlatList, Pressable, Text } from "react-native";
import type { Thread } from "stream-chat";
import { useThreadsContext } from "stream-chat-react-native";

const keyExtractor = (thread: Thread) => thread.id;

export const CompactThreadList = () => {
  const { isLoading, loadMore, onThreadSelect, threads } = useThreadsContext();

  if (isLoading) return <Text>Loading threads...</Text>;

  return (
    <FlatList
      data={threads}
      keyExtractor={keyExtractor}
      onEndReached={loadMore}
      renderItem={({ item }) => (
        <Pressable onPress={() => onThreadSelect?.(item)}>
          <Text numberOfLines={1}>{item.id}</Text>
        </Pressable>
      )}
    />
  );
};
```

Register it as `ThreadListComponent`. It replaces the banner too, so render `ThreadListUnreadBanner` from `useComponentsContext()` to keep it. A row of your own reads the thread's state with `useStateStore(thread.state, selector)`; see [Thread and thread manager](https://getstream.io/chat/docs/sdk/react-native/v10/reference/state/thread-and-thread-manager/#thread-state).

## Related hooks

| Hook                         | Returns                                                                                   |
| ---------------------------- | ----------------------------------------------------------------------------------------- |
| `useThreadsContext()`        | the values above; throws outside a `ThreadList`                                           |
| `useThreadListItemContext()` | the thread of the row being rendered, and the values the row shows                        |
| `useStateStore()`            | a selection of `client.threads.state`, `client.threads.paginator.state` or `thread.state` |

`client.threads.state` holds `unreadThreadCount` and `unseenThreadIds`, and `client.threads.paginator.state` the threads, `isLoading` and `lastQueryError`. See [useThreadsContext](https://getstream.io/chat/docs/sdk/react-native/v10/reference/hooks/loading-data-hooks/#usethreadscontext) and [Thread and thread manager](https://getstream.io/chat/docs/sdk/react-native/v10/reference/state/thread-and-thread-manager/).

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/thread-list/threadlist/](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/thread-list/threadlist/).