# Reaction components

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

Reactions show in three places: on the message, as a list above or under the bubble; in the message menu, as a picker above the message; and in a bottom sheet that lists who reacted. Every component on this page is an override key of the same name. The `ReactionListItemWrapper` key has no effect; see [ReactionListItemWrapper](#reactionlistitemwrapper). [Reactions](https://getstream.io/chat/docs/sdk/react-native/v10/features/messaging/reactions/) covers the feature across the layers.

## Best practices

- Set the reactions on offer with `supportedReactions` on `Channel` or `Thread`. Every component here reads them from `MessagesContext`, and a reaction of a type not in the list doesn't show on messages.
- Pick the layout with `reactionListPosition` and `reactionListType` on `Channel` before you replace a component.
- Change what a tap on a reaction does with `onPressMessage` on `Channel`: the payload's `emitter` is `reactionList` and `additionalInfo.reactionType` the pressed type. [Toggling a reaction with a tap](https://getstream.io/chat/docs/sdk/react-native/v10/features/messaging/reactions/#toggling-a-reaction-with-a-tap) shows it.
- Change what picking a reaction does with `selectReaction` or `handleReaction` on `Channel`, not by replacing the picker.

## Basic usage

This wrapper shows the reactions above the bubble as separate pills without counts:

```tsx title="src/ReactionListTopWithoutCounts.tsx"
import {
  ReactionListTop,
  type ReactionListTopProps,
  WithComponents,
} from "stream-chat-react-native";

const ReactionListTopWithoutCounts = (props: ReactionListTopProps) => (
  <ReactionListTop {...props} showCount={false} type="segmented" />
);

const overrides = { ReactionListTop: ReactionListTopWithoutCounts };

export const MessagesWithPlainReactions = ({
  children,
}: {
  children: React.ReactNode;
}) => <WithComponents overrides={overrides}>{children}</WithComponents>;
```

[Custom reactions](https://getstream.io/chat/docs/sdk/react-native/v10/ui-cookbook/message/custom-reactions/) changes the reactions on offer and their icons.

## The reactions on a message

`MessageItemView` renders `ReactionListTop` above the bubble with `reactionListPosition="top"`, the default, and `ReactionListBottom` under it with `"bottom"`, passing `reactionListType` as `type`. Both render nothing while the message has no reaction of a supported type. A message's reactions come from `MessageContext.reactions`: one entry for each type, with its count and whether the user gave it, the oldest type first.

Pressing a reaction reports the `reactionList` emitter, and by default opens the reactions sheet with that type selected. Pressing the clustered list, or the "+N" pill, opens it with every type.

### ReactionListTop

With `type="clustered"` it renders `ReactionListClustered`. With any other `type`, or none, it renders up to four `ReactionListItem` pills in a row, then a `ReactionListCountItem` with the number of other types. A prop set here is used when it's truthy; otherwise the context value is.

| Prop                   | Type                                                   | Default                | Description                                       |
| ---------------------- | ------------------------------------------------------ | ---------------------- | ------------------------------------------------- |
| `alignment`            | `Alignment`                                            | from `MessageContext`  | Puts the list at the bubble's right or left edge. |
| `hasReactions`         | `boolean`                                              | from `MessageContext`  | Whether the message has reactions.                |
| `onLongPress`          | `(payload: PressableHandlerPayload) => void`           | from `MessageContext`  | Called on a long press on a pill.                 |
| `onPress`              | `(payload: MessagePressableHandlerPayload) => void`    | from `MessageContext`  | Called on a press on a pill.                      |
| `onPressIn`            | `((payload: PressableHandlerPayload) => void) \| null` | from `MessageContext`  | Called when a press on a pill starts.             |
| `preventPress`         | `boolean`                                              | from `MessageContext`  | Turns off presses.                                |
| `reactionListType`     | `"clustered" \| "segmented"`                           |                        | Not used. The list follows `type`.                |
| `reactions`            | `ReactionSummary[]`                                    | from `MessageContext`  | The reactions to show.                            |
| `showCount`            | `boolean`                                              | `true`                 | Shows each pill's count.                          |
| `showReactionsOverlay` | `(selectedReaction?: string) => void`                  | from `MessageContext`  | Opens the reactions sheet.                        |
| `supportedReactions`   | `ReactionData[]`                                       | from `MessagesContext` | The reactions on offer, for the icons.            |
| `type`                 | `"clustered" \| "segmented"`                           |                        | `'clustered'` renders `ReactionListClustered`.    |

### ReactionListBottom

With `type="segmented"` it renders a `ReactionListItem` pill for every type, five to a row, or six without counts. With any other `type`, or none, it renders `ReactionListClustered`. A prop set here is used when it's truthy; otherwise the context value is.

| Prop                   | Type                                                   | Default                | Description                                 |
| ---------------------- | ------------------------------------------------------ | ---------------------- | ------------------------------------------- |
| `alignment`            | `Alignment`                                            | from `MessageContext`  | Aligns the rows left or right.              |
| `hasReactions`         | `boolean`                                              | from `MessageContext`  | Whether the message has reactions.          |
| `onLongPress`          | `(payload: PressableHandlerPayload) => void`           | from `MessageContext`  | Called on a long press on a pill.           |
| `onPress`              | `(payload: MessagePressableHandlerPayload) => void`    | from `MessageContext`  | Called on a press on a pill.                |
| `onPressIn`            | `((payload: PressableHandlerPayload) => void) \| null` | from `MessageContext`  | Called when a press on a pill starts.       |
| `preventPress`         | `boolean`                                              | from `MessageContext`  | Turns off presses.                          |
| `reactions`            | `ReactionSummary[]`                                    | from `MessageContext`  | The reactions to show.                      |
| `showCount`            | `boolean`                                              | `true`                 | Shows each pill's count.                    |
| `showReactionsOverlay` | `(selectedReaction?: string) => void`                  | from `MessageContext`  | Opens the reactions sheet.                  |
| `supportedReactions`   | `ReactionData[]`                                       | from `MessagesContext` | The reactions on offer, for the icons.      |
| `type`                 | `"clustered" \| "segmented"`                           |                        | `'segmented'` renders a pill for each type. |

### ReactionListClustered

Renders the icons of up to four reaction types in one pill, followed by the number of other types when there are more. Pressing it reports the `reactionList` emitter, and by default opens the reactions sheet with every type.

| Prop                   | Type                                                   | Default                | Description                            |
| ---------------------- | ------------------------------------------------------ | ---------------------- | -------------------------------------- |
| `accessibilityLabel`   | `string`                                               |                        | The pill's accessibility label.        |
| `containerStyle`       | `StyleProp<ViewStyle>`                                 |                        | Style of the pill.                     |
| `hasReactions`         | `boolean`                                              | from `MessageContext`  | Whether the message has reactions.     |
| `onPress`              | `(payload: MessagePressableHandlerPayload) => void`    | from `MessageContext`  | Called on a press.                     |
| `onPressIn`            | `((payload: PressableHandlerPayload) => void) \| null` | from `MessageContext`  | Called when a press starts.            |
| `preventPress`         | `boolean`                                              | from `MessageContext`  | Turns off presses.                     |
| `reactions`            | `ReactionSummary[]`                                    | from `MessageContext`  | The reactions to show.                 |
| `showReactionsOverlay` | `(selectedReaction?: string) => void`                  | from `MessageContext`  | Opens the reactions sheet.             |
| `supportedReactions`   | `ReactionData[]`                                       | from `MessagesContext` | The reactions on offer, for the icons. |

### ReactionListItem

Renders one reaction type as a pill: its icon, or the `Unknown` icon when the type isn't in `supportedReactions`, and its count. A press or a long press reports the `reactionList` emitter with `additionalInfo.reactionType`, and by default opens the reactions sheet at that type.

| Prop                   | Type                                                   | Default  | Description                                                                                          |
| ---------------------- | ------------------------------------------------------ | -------- | ---------------------------------------------------------------------------------------------------- |
| `onLongPress`          | `(payload: PressableHandlerPayload) => void`           |          | Called on a long press.                                                                              |
| `onPress`              | `(payload: MessagePressableHandlerPayload) => void`    |          | Called on a press.                                                                                   |
| `onPressIn`            | `((payload: PressableHandlerPayload) => void) \| null` |          | Called when a press starts.                                                                          |
| `preventPress`         | `boolean`                                              |          | Turns off presses.                                                                                   |
| `reaction`             | `ReactionSummary`                                      | required | The reaction type, with its `count`.                                                                 |
| `selected`             | `boolean`                                              | `false`  | Highlights the pill, and tells screen readers the user reacted. The lists pass the reaction's `own`. |
| `showCount`            | `boolean`                                              | `true`   | Shows the count.                                                                                     |
| `showReactionsOverlay` | `(selectedReaction?: string) => void`                  |          | Opens the reactions sheet.                                                                           |
| `supportedReactions`   | `ReactionData[]`                                       |          | The reactions on offer, for the icon.                                                                |

`ReactionListItem` reads nothing from context: the lists pass every prop.

### ReactionListCountItem

Renders "+3", the number of reaction types `ReactionListTop` leaves out. It renders nothing for a `count` of 0. Pressing it opens the reactions sheet with every type.

| Prop                   | Type                                                   | Default  | Description                 |
| ---------------------- | ------------------------------------------------------ | -------- | --------------------------- |
| `count`                | `number`                                               | required | The number to show.         |
| `onLongPress`          | `(payload: PressableHandlerPayload) => void`           |          | Called on a long press.     |
| `onPress`              | `(payload: MessagePressableHandlerPayload) => void`    |          | Called on a press.          |
| `onPressIn`            | `((payload: PressableHandlerPayload) => void) \| null` |          | Called when a press starts. |
| `preventPress`         | `boolean`                                              |          | Turns off presses.          |
| `selected`             | `boolean`                                              |          | Highlights the pill.        |
| `showReactionsOverlay` | `(selectedReaction?: string) => void`                  |          | Opens the reactions sheet.  |

### ReactionListItemWrapper

The `Pressable` pill the items and the clustered list render in. They import it directly, so the `ReactionListItemWrapper` override key has no effect; style the pill through `theme.messageItemView.reactionListItemWrapper`. It takes every `Pressable` prop, and:

| Prop       | Type                   | Default | Description                                 |
| ---------- | ---------------------- | ------- | ------------------------------------------- |
| `selected` | `boolean`              | `false` | Uses the selected background.               |
| `style`    | `StyleProp<ViewStyle>` |         | Style of the pill, applied after the SDK's. |

## The reaction picker

`MessageReactionPicker` renders above the message while the message menu is open: the reactions of `supportedReactions` with `isMain`, the ones the user gave highlighted, and a button that opens a sheet with the full emoji list. Picking a reaction closes the menu, then calls `handleReaction`. It renders nothing when the user can't send reactions.

| Prop                 | Type                                      | Default  | Description                                                                                                                          |
| -------------------- | ----------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `dismissOverlay`     | `() => void`                              | required | Closes the message menu.                                                                                                             |
| `handleReaction`     | `(reactionType: string) => Promise<void>` |          | Called with the picked type after the menu closes. `Message` passes the message's `handleReaction` when the user can send reactions. |
| `supportedReactions` | `ReactionData[]`                          |          | Not used. The picker reads them from `MessagesContext`.                                                                              |

The emoji sheet lists a fixed set of emojis, whatever `supportedReactions` holds.

## The reactions sheet

`MessageUserReactions` renders in a bottom sheet, which `showReactionsOverlay` opens: the total count, a row of the message's reaction types with their counts, and the users who reacted, loaded page by page, newest first. Picking a type in the row filters the users. The **+** button at the start of the row shows the emoji list; picking an emoji calls the message's `handleReaction` and closes the sheet.

| Prop                 | Type             | Default                              | Description                                                                        |
| -------------------- | ---------------- | ------------------------------------ | ---------------------------------------------------------------------------------- |
| `message`            | `LocalMessage`   |                                      | The message whose reactions show. `Message` passes it; it isn't read from context. |
| `reactions`          | `Reaction[]`     | the reactions loaded from the server | The users to list, in place of the loaded ones.                                    |
| `selectedReaction`   | `string`         |                                      | The type selected when the sheet opens.                                            |
| `supportedReactions` | `ReactionData[]` | from `MessagesContext`               | The reactions on offer. Types not in it don't show in the row.                     |

### MessageUserReactionsItem

Renders one user in the sheet, with the `MessageUserReactionsAvatar` override, the name, or "You" with "Tap to remove", and the reaction's icon. Pressing the user's own reaction removes it through `handleReaction`. It isn't exported; replace it with the `MessageUserReactionsItem` key.

| Prop                 | Type             | Default  | Description                                                        |
| -------------------- | ---------------- | -------- | ------------------------------------------------------------------ |
| `reaction`           | `Reaction`       | required | The reaction: the user's `id`, `name` and `image`, and the `type`. |
| `supportedReactions` | `ReactionData[]` | required | The reactions on offer, for the icon.                              |

### MessageUserReactionsAvatar

Renders the avatar of the user who reacted, or their initials.

| Prop       | Type                                            | Default  | Description                                                  |
| ---------- | ----------------------------------------------- | -------- | ------------------------------------------------------------ |
| `reaction` | `Reaction`                                      | required | The reaction, with the user's `name` and `image`.            |
| `size`     | `"sm" \| "md" \| "lg" \| "xl" \| "xs" \| "2xl"` | `'lg'`   | The avatar's size. `MessageUserReactionsItem` passes `'md'`. |

## Related hooks

- `useMessageContext()` returns the message's `reactions`, `hasReactions`, `handleReaction`, `handleToggleReaction` and `showReactionsOverlay`.
- `useMessagesContext()` returns `supportedReactions`, `reactionListPosition` and `reactionListType`.
- `useFetchReactions({ message, reactionType, sort })` loads the users who reacted, as the sheet does. See [Message hooks](https://getstream.io/chat/docs/sdk/react-native/v10/reference/hooks/message-hooks/#usefetchreactions).

---

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