# Channel preview

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

Each row of a [`ChannelList`](https://getstream.io/chat/docs/sdk/react-native/v10/component-reference/channel-list/channellist/) is a `ChannelPreview`. It reads the row's values from the channel's stores, such as whether the channel is muted, the unread count and the latest message, wraps the row in its swipe actions, and renders the `ChannelPreview` override key with those values as props. The default for that key is `ChannelPreviewView`, the row's look. [Channel list UI](https://getstream.io/chat/docs/sdk/react-native/v10/ui/components/channel-list-ui/#rows) explains what each value is read from.

>
> **Note:** The exported `ChannelPreview` component and the `ChannelPreview` override key are different things. The component is the row wrapper that `ChannelListView` renders for each channel, and it has no key. The key is the row's content, which the wrapper renders: `ChannelPreviewView` by default.
>

## Best practices

- To change the look and keep the values, register your own component as the `ChannelPreview` key. It gets the same props as `ChannelPreviewView`, and can render `ChannelPreviewView` itself.
- To change only one part, such as the title or the unread badge, override that part's key instead of the whole row. See [Parts](#parts).
- Keep a row light, since it renders for every channel in the list.
- Use the props a row gets, such as `unread` and `lastMessage`, rather than reading them from the channel again. They're reactive, and `channel.data` isn't.
- A row of your own that doesn't render `ChannelPreviewView` calls `onSelect` from `useChannelsContext()` itself. The SDK doesn't export the registry of open swipe actions, so such a row can't close them on a tap as the default does.

## Basic usage

The default row shows the time of the latest message from the `timestamp.ChannelPreviewStatus` translation key. `ChannelPreviewView` takes `formatLatestMessageDate` to format it yourself, but `ChannelPreview` doesn't pass it, so register a row that does:

```tsx title="src/RowsWithShortDates.tsx"
import type { PropsWithChildren } from "react";
import { ChannelPreviewView, WithComponents } from "stream-chat-react-native";
import type {
  ChannelPreviewViewProps,
  ComponentOverrides,
} from "stream-chat-react-native";

const formatLatestMessageDate = (date: Date) =>
  date.toLocaleDateString(undefined, { day: "numeric", month: "short" });

const RowWithShortDate = (props: ChannelPreviewViewProps) => (
  <ChannelPreviewView
    {...props}
    formatLatestMessageDate={formatLatestMessageDate}
  />
);

const overrides: ComponentOverrides = { ChannelPreview: RowWithShortDate };

export const RowsWithShortDates = ({ children }: PropsWithChildren) => (
  <WithComponents overrides={overrides}>{children}</WithComponents>
);
```

The [Preview UI cookbook](https://getstream.io/chat/docs/sdk/react-native/v10/ui-cookbook/channel-list/preview-ui/) builds a row from scratch.

## What a row does

`ChannelPreview`:

- reads `muted`, `pinned` and `unread` from `channel.state`, and `lastMessage` from `channel.messagePaginator.aggregateState`. `unread` is the current user's unread count, and `0` while the channel is muted.
- replaces `lastMessage` with its translation into the user's language, when the message has one.
- subscribes the channel's composer to draft events, so the row shows the user's draft.
- wraps the row in its swipe actions, unless `swipeActionsEnabled` on `ChannelList` is `false`.

The default `ChannelPreviewView`:

- is a `Pressable`. A tap closes any open swipe actions in the list, or calls `onSelect(channel)` when none are open.
- renders the avatar at the start, and the title with the muted and pinned icons, the time of the latest message and the unread badge on its first line.
- renders the message line on its second line: who is typing, the draft, "No messages yet", the poll's label, "Message failed to send", or the latest message after its delivery status, the first that applies.
- places the muted and pinned icons after the title, or at the end of the message line, as `mutedStatusPosition` and `pinnedStatusPosition` say.
- is memoized, so it renders again only when one of its props changes.

## Props

`ChannelPreview` takes these props:

| Prop      | Type         | Default                       | Description                                                                           |
| --------- | ------------ | ----------------------------- | ------------------------------------------------------------------------------------- |
| `channel` | `Channel`    | required                      | The row's channel.                                                                    |
| `client`  | `StreamChat` | the client from `ChatContext` | The client the row reads the current user's id from, to find the user's unread count. |

The `ChannelPreview` key, `ChannelPreviewView` by default, gets these props. `ChannelPreview` passes `channel`, `muted`, `pinned`, `unread` and `lastMessage`; `ChannelPreviewView` reads the rest from `ChannelsContext` unless you pass them.

| Prop                      | Type                                | Default                | Description                                                                                                                                                                                                 |
| ------------------------- | ----------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `channel`                 | `Channel`                           | required               | The row's channel.                                                                                                                                                                                          |
| `formatLatestMessageDate` | `(date: Date) => string`            |                        | Formats the time of the latest message. Without it, the row uses the `timestamp.ChannelPreviewStatus` translation: the time today, "Yesterday", the weekday within the last week, and the date before that. |
| `lastMessage`             | `LastMessageType`                   |                        | The latest message of the channel, translated when the message has a translation. `LastMessageType` is `LocalMessage \| MessageResponse`.                                                                   |
| `maxUnreadCount`          | `number`                            | from `ChannelsContext` | The highest count the unread badge shows.                                                                                                                                                                   |
| `muted`                   | `boolean`                           |                        | Whether the current user muted the channel.                                                                                                                                                                 |
| `mutedStatusPosition`     | `'trailingBottom' \| 'inlineTitle'` | from `ChannelsContext` | Where the muted icon shows: after the title, or at the end of the message line.                                                                                                                             |
| `onSelect`                | `(channel: Channel) => void`        | from `ChannelsContext` | Called with the channel when the row is tapped while no swipe actions are open.                                                                                                                             |
| `pinned`                  | `boolean`                           |                        | Whether the current user pinned the channel.                                                                                                                                                                |
| `pinnedStatusPosition`    | `'trailingBottom' \| 'inlineTitle'` | from `ChannelsContext` | Where the pinned icon shows: after the title, or at the end of the message line.                                                                                                                            |
| `unread`                  | `number`                            |                        | The current user's unread messages in the channel. `0` while the channel is muted.                                                                                                                          |

## Parts

`ChannelPreviewView` renders each part through an override key, with these props:

| Override key                 | Default                      | Gets                                                | Shows                                                                          |
| ---------------------------- | ---------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------ |
| `ChannelPreviewAvatar`       | `ChannelAvatar`              | `channel`, `size: 'xl'`                             | The channel's image, or its members' avatars                                   |
| `ChannelPreviewTitle`        | `ChannelPreviewTitle`        | `channel`                                           | The channel's display name. The default also takes a `title` that replaces it. |
| `ChannelPreviewMutedStatus`  | `ChannelPreviewMutedStatus`  | nothing                                             | The muted icon                                                                 |
| `ChannelPreviewPinnedStatus` | `ChannelPreviewPinnedStatus` | nothing                                             | The pinned icon                                                                |
| `ChannelPreviewStatus`       | `ChannelPreviewStatus`       | `channel`, `formatLatestMessageDate`, `lastMessage` | The time of the latest message                                                 |
| `ChannelPreviewUnreadCount`  | `ChannelPreviewUnreadCount`  | `channel`, `maxUnreadCount`, `unread`               | The unread badge, hidden at `0`                                                |
| `ChannelPreviewMessage`      | `ChannelPreviewMessage`      | `channel`, `lastMessage`                            | The message line                                                               |

`ChannelPreviewMessage` renders three more keys:

| Override key                          | Default                               | Gets                     | Shows                                                                                                                                      |
| ------------------------------------- | ------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `ChannelPreviewTypingIndicator`       | `ChannelPreviewTypingIndicator`       | `channel`, `usersTyping` | Who is typing, in place of the message line                                                                                                |
| `ChannelPreviewLastMessage`           | `ChannelLastMessagePreview`           | `message`                | The text of the latest message, or of the draft                                                                                            |
| `ChannelPreviewMessageDeliveryStatus` | `ChannelMessagePreviewDeliveryStatus` | `channel`, `message`     | The sent, delivered or read mark of the user's own latest message, or the sender's name before another member's message in a group channel |

Every default is exported under the name in the Default column, so a replacement can render it and add to it.

## Related hooks

- `useChannelPreviewDisplayName(channel)` returns the title the default row shows.
- `useChannelPreviewDisplayPresence(channel)` returns `true` when the channel has two members and the other one is online.
- `useChannelTypingState({ channel })` returns who is typing in the channel.
- `useChannelPreviewDraftMessage({ channel })` returns the user's draft in the channel.
- `useIsChannelMuted(channel)` returns the channel's mute status, `{ muted, createdAt, expiresAt }`, and `useIsChannelPinned(channel)` whether the user pinned it.

Their signatures are on [Channel preview hooks](https://getstream.io/chat/docs/sdk/react-native/v10/reference/hooks/channel-preview-hooks/).

---

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