ThreadList
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 describes what it shows, and Replies and threads how the list loads and stays current.
Best practices
- Render it anywhere inside
Chat. It needs noChannel. - Pass the focus state of its screen as
isFocused, such asuseIsFocused()from React Navigation. The list keepsclient.threadsactive only while it'strue, so a hidden screen doesn't keep reloading the list. - Render one
ThreadListat a time. Each one deactivatesclient.threadswhen 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 rendersThreadwith it. WithoutonThreadSelect, tapping a row does nothing. - Change the rows through the
ThreadListItemoverride key, and keep them light: rows mount and unmount as the user scrolls.
Basic usage
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 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; ThreadListLoadingMoreIndicatorafter the last row while the next page loads, orThreadListEmptyPlaceholder, "Reply to a message to start a thread", when there are no threads;- a
NotificationListfor 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 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 |
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 |
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:
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.
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 and Thread and thread manager.