# ThreadListItem

`ThreadListItem` renders one row of [`ThreadList`](https://getstream.io/chat/docs/sdk/react/component-reference/thread-list/threadlist/). It has two parts:

- `ThreadListItem` gives the row its thread, which `useThreadListItemContext()` returns, and renders `ThreadListItemUI`.
- `ThreadListItemUI` is the row's look: a button that opens the thread.

[Thread list UI](https://getstream.io/chat/docs/sdk/react/ui/components/thread-list-ui/#thread-list-items) describes what a thread list item shows and which stores it reads.

## Best practices

- Replace `ThreadListItemUI` to change how a row looks, and keep `ThreadListItem`. Replace `ThreadListItem` only to change what a row receives.
- Read the row's thread with `useThreadListItemContext()` and its state with `useStateStore(thread.state, selector)`. The row already has the thread, so don't query it again.
- Open the thread with `openThread(thread)` from `useWorkspaceNavigation()`, and mark the open one with `isThreadActive(thread.id)`, as the default row does.
- Keep the row light: the list is virtualized, so rows mount and unmount as the user scrolls.
- To change what screen readers announce for a row, wrap the default `ThreadListItemUI` and pass `accessibleLabelConfig`.

## What the default row shows

`ThreadListItemUI` renders a `button` with the `option` role. It shows the avatar of the latest reply's author, the channel's name, a one-line preview of the parent message, the avatars of up to three participants, the reply count, the time of the latest reply and the user's unread count.

The row renders the `Avatar`, `AvatarStack`, `SummarizedMessagePreview` and `Timestamp` override keys, so an override of one of them for the channel list or the messages shows in the thread list too.

The preview is the `<SummarizedMessagePreview/>` line the channel list shows, without inline Markdown. The row's accessible name reads only the preview's words. [The last-message line](https://getstream.io/chat/docs/sdk/react/component-reference/channel-list/channel-preview/#the-last-message-line) lists what stays.

Clicking it opens the thread; ⌘/ctrl-click asks the layout to open it beside the open one. An unseen thread, one that got replies while it wasn't in the list, is highlighted for two seconds when a reload brings it in.

## UI customization

This row keeps the default look and adds the number of participants to its accessible name:

```tsx
import type {
  ThreadListItemLabelConfig,
  ThreadListItemUIProps,
} from "stream-chat-react";
import {
  DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER,
  ThreadList,
  ThreadListItemUI,
  WithComponents,
} from "stream-chat-react";

const accessibleLabelConfig: ThreadListItemLabelConfig = {
  order: [...DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER, "participants"],
  parts: {
    participants: ({ participantCount }) =>
      participantCount ? `${participantCount} participants` : undefined,
  },
};

const LabelledThreadListItemUI = (props: ThreadListItemUIProps) => (
  <ThreadListItemUI {...props} accessibleLabelConfig={accessibleLabelConfig} />
);

const overrides = { ThreadListItemUI: LabelledThreadListItemUI };

export const ThreadsSidebar = () => (
  <WithComponents overrides={overrides}>
    <ThreadList />
  </WithComponents>
);
```

A part that isn't listed in `order` never renders. `defaultThreadListItemLabelParts` holds the default parts, and `composeThreadListItemAccessibleLabel(data, config)` builds the label for a row of your own. For a row with a different look, see [Thread list UI](https://getstream.io/chat/docs/sdk/react/ui/components/thread-list-ui/#replacing-parts).

## Props

### ThreadListItem

| Prop                    | Type                    | Default  | Description                                                                                                 |
| ----------------------- | ----------------------- | -------- | ----------------------------------------------------------------------------------------------------------- |
| `thread`                | `Thread`                | required | The row's thread. `ThreadList` passes each thread of `client.threads.paginator`.                            |
| `threadListItemUIProps` | `ThreadListItemUIProps` | none     | Props passed to `ThreadListItemUI`. `ThreadList` passes `resetHighlighting` for a thread that just arrived. |

### ThreadListItemUI

`ThreadListItemUI` also takes every `button` prop. They're applied after the SDK's own, so they replace them. `onClick` is the exception: it runs after the SDK's handler, which opens the thread.

| Prop                    | Type                        | Default                                                      | Description                                                                                                                        |
| ----------------------- | --------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `accessibleLabelConfig` | `ThreadListItemLabelConfig` | the default parts, in `DEFAULT_THREAD_LIST_ITEM_LABEL_ORDER` | How the row's `aria-label` is composed: `parts` to add or replace, their `order`, the `separator`, or `build` for the whole label. |
| `resetHighlighting`     | `() => void`                | none                                                         | Set for a row that just arrived. The row is highlighted while it's set, and calls it after two seconds.                            |

## Related hooks

| Hook                                    | Returns                                                                                  |
| --------------------------------------- | ---------------------------------------------------------------------------------------- |
| `useThreadListItemContext()`            | the row's thread, or `undefined` outside a `ThreadListItem`                              |
| `useWorkspaceNavigation()`              | `openThread` and `isThreadActive`                                                        |
| `useStateStore(thread.state, selector)` | a selection of the thread's state: parent message, reply count, participants, read state |

See [useThreadListItemContext](https://getstream.io/chat/docs/sdk/react/reference/hooks/state-and-entity-hooks/#usethreadlistitemcontext) and, for the fields of `thread.state`, [Thread and thread manager](https://getstream.io/chat/docs/sdk/react/reference/state/thread-and-thread-manager/).

---

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