# Message Hooks

The React Chat SDK exports hooks that help you build custom message UI without re-implementing channel actions manually.

## Best Practices

- Prefer these hooks over re-creating message action logic yourself.
- Keep hook handlers attached to explicit user interactions.
- Use `useMessageContext()` as the source of truth for the current message.
- Test permission-dependent hooks with realistic roles and capabilities.
- Use the message composer for edit flows instead of maintaining local message edit state.

## Hooks

### Action and moderation hooks

- [`useActionHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useActionHandler.ts) handles slash-command style message actions.
- [`useDeleteHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useDeleteHandler.ts) deletes a message.
- [`useFlagHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useFlagHandler.ts) flags a message.
- [`useMarkUnreadHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useMarkUnreadHandler.ts) marks a message and following messages unread.
- [`useMuteHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useMuteHandler.ts) mutes the message sender.
- [`usePinHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/usePinHandler.ts) handles message pinning.
- [`useRetryHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useRetryHandler.ts) retries a failed message send.

### Thread, reaction, and mention hooks

- [`useOpenThreadHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useOpenThreadHandler.ts) opens a thread for the current message.
- [`useReactionHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useReactionHandler.ts) adds or removes a reaction.
- [`useReactionsFetcher`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useReactionsFetcher.ts) loads message reactions.
- [`useMentionsHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useMentionsHandler.ts) provides click and hover handlers for mentions.

### User helper hooks

- [`useUserHandler`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useUserHandler.ts) resolves avatar/name click and hover handlers.
- [`useUserRole`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/hooks/useUserRole.ts) computes permission-dependent message capabilities.

## Examples

### useDeleteHandler

```tsx
import { useDeleteHandler, useMessageContext } from "stream-chat-react";

const CustomMessage = () => {
  const { message } = useMessageContext();
  const handleDelete = useDeleteHandler(message);

  const onDelete = async () => {
    try {
      await handleDelete();
    } catch {
      // The SDK already shows its default delete error notification.
    }
  };

  return <button onClick={onDelete}>Delete {message.id}</button>;
};
```

For unsent or network-failed messages, `useDeleteHandler()` removes the message locally. For server-side delete failures, it now rethrows after the SDK shows its default error notification.

### useMarkUnreadHandler

```tsx
import {
  useMarkUnreadHandler,
  useMessageContext,
  useUserRole,
} from "stream-chat-react";

const MarkUnreadButton = () => {
  const { message } = useMessageContext();
  const { canMarkUnread } = useUserRole(message);
  const handleMarkUnread = useMarkUnreadHandler(message);

  if (!canMarkUnread) return null;

  return <button onClick={handleMarkUnread}>Mark unread</button>;
};
```

`markUnread` is only available for foreign messages when the connected user also has the required `read-events` capability.

### useReactionHandler

```tsx
import { useMessageContext, useReactionHandler } from "stream-chat-react";

const CustomReactionButtons = () => {
  const { message } = useMessageContext();
  const handleReaction = useReactionHandler(message);

  return (
    <>
      <button onClick={(event) => handleReaction("love", event)}>Love</button>
      <button onClick={(event) => handleReaction("fire", event)}>Fire</button>
    </>
  );
};
```

### useRetryHandler

```tsx
import { useMessageContext, useRetryHandler } from "stream-chat-react";

const RetryButton = () => {
  const { message } = useMessageContext();
  const handleRetry = useRetryHandler(message);

  return <button onClick={handleRetry}>Retry</button>;
};
```

### useUserRole

```tsx
import { useMessageContext, useUserRole } from "stream-chat-react";

const MessageCapabilities = () => {
  const { message } = useMessageContext();
  const { canDelete, canEdit, canReply } = useUserRole(message);

  return (
    <div>
      {String(canEdit)} / {String(canDelete)} / {String(canReply)}
    </div>
  );
};
```

If your message UI needs editing behavior, initialize the current message in the message composer rather than relying on a dedicated message edit hook.


---

This page was last updated at 2026-05-22T16:32:13.456Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/hooks/message-hooks/](https://getstream.io/chat/docs/sdk/react/hooks/message-hooks/).