# MessageComposerContext

> **Info:** This is release candidate documentation for **Stream Chat React SDK v15**. For the latest stable version, see the [latest version (v14)](https://getstream.io/chat/docs/sdk/react/).

`MessageComposerContext` holds the props of the [`MessageComposer`](https://getstream.io/chat/docs/sdk/react/v15/component-reference/message-composer/messagecomposer/) around a component, and the bindings of its input: the textarea ref, the paste handler and the voice recorder. Every part of the composer UI can read it with `useMessageComposerContext()`. It holds UI settings, not the message: the text, the attachments and the rest are in the composer's stores, which [Message composer UI](https://getstream.io/chat/docs/sdk/react/v15/ui/components/message-composer-ui/#what-each-part-reads) maps to the parts that read them.

## Best practices

- Read the message being written from the composer, with `useMessageComposerController()` and `useStateStore`, not from this context.
- Read the cooldown with [`useIsCooldownActive`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/channel-and-thread-hooks/#useiscooldownactive) or [`useCooldownRemaining`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/channel-and-thread-hooks/#usecooldownremaining), or render [`CooldownTimer`](https://getstream.io/chat/docs/sdk/react/v15/component-reference/message-composer/composer-ui-components/). It isn't in this context.
- This context doesn't decide which composer is used. To have `MessageComposer` write into a composer you own, see [Supplying a composer](https://getstream.io/chat/docs/sdk/react/v15/component-reference/message-composer/messagecomposer/#supplying-a-composer).
- Render components that read it inside `MessageComposer`, for example as an override of one of its parts. `useMessageComposerContext()` throws outside it, and `useIsWithinMessageComposerContext()` tells whether a component is inside one.

## Basic usage

This composer UI shows a hint below the default UI when the user has blocked the microphone:

```tsx
import {
  MessageComposer,
  MessageComposerUI,
  useMessageComposerContext,
  WithComponents,
} from "stream-chat-react";

const ComposerUIWithMicrophoneHint = () => {
  const { audioRecordingEnabled, recordingController } =
    useMessageComposerContext();
  const microphoneBlocked =
    audioRecordingEnabled && recordingController.permissionState === "denied";

  return (
    <>
      <MessageComposerUI />
      {microphoneBlocked && (
        <p className="composer-hint">
          Allow the microphone to record voice messages.
        </p>
      )}
    </>
  );
};

const overrides = { MessageComposerUI: ComposerUIWithMicrophoneHint };

export const ComposerWithHint = () => (
  <WithComponents overrides={overrides}>
    <MessageComposer audioRecordingEnabled />
  </WithComponents>
);
```

## Values

| Value                           | Type                                                                                                          | Description                                                                                                                                                                                                  |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `additionalTextareaProps`       | `Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "defaultValue" \| "style" \| "disabled" \| "value">` | The `MessageComposer` prop. `TextareaComposer` spreads it onto the `<textarea>`.                                                                                                                             |
| `asyncMessagesMultiSendEnabled` | `boolean \| undefined`                                                                                        | The `MessageComposer` prop: whether a finished voice recording stays in the composer instead of being sent.                                                                                                  |
| `audioRecordingConfig`          | `CustomAudioRecordingConfig \| undefined`                                                                     | In the type, but always `undefined`. The recorder in `recordingController` gets the `MessageComposer` prop directly.                                                                                         |
| `audioRecordingEnabled`         | `boolean \| undefined`                                                                                        | The `MessageComposer` prop: whether voice recording is turned on.                                                                                                                                            |
| `emojiSearchIndex`              | `EmojiSearchIndex \| undefined`                                                                               | The `MessageComposer` prop, or the `emojiSearchIndex` key of `WithComponents`. No built-in component reads it.                                                                                               |
| `focus`                         | `boolean \| undefined`                                                                                        | The `MessageComposer` prop. `TextareaComposer` focuses the input on mount, and again whenever the attachments or the quoted message change.                                                                  |
| `hideSendButton`                | `boolean \| undefined`                                                                                        | The `MessageComposer` prop. `MessageComposerActions` renders nothing while it's set, unless an AI reply can be stopped.                                                                                      |
| `maxRows`                       | `number \| undefined`                                                                                         | The `MessageComposer` prop. `TextareaComposer` uses `10` when neither it nor its own `maxRows` is set.                                                                                                       |
| `minRows`                       | `number \| undefined`                                                                                         | The `MessageComposer` prop.                                                                                                                                                                                  |
| `onPaste`                       | `(event: React.ClipboardEvent<HTMLTextAreaElement>) => void`                                                  | The paste handler of the input. It inserts pasted text, or uploads the pasted files when there's no text.                                                                                                    |
| `parent`                        | `LocalMessage \| undefined`                                                                                   | The `MessageComposer` prop. No built-in component reads it.                                                                                                                                                  |
| `recordingController`           | `RecordingController`                                                                                         | The voice recorder: `recorder`, the `recording` in progress, `recordingState`, the microphone `permissionState`, and `completeRecording()`. `recorder` is `undefined` unless `audioRecordingEnabled` is set. |
| `shouldSubmit`                  | `((event: React.KeyboardEvent<HTMLTextAreaElement>) => boolean) \| undefined`                                 | The `MessageComposer` prop.                                                                                                                                                                                  |
| `textareaRef`                   | `React.RefObject<HTMLTextAreaElement \| null \| undefined>`                                                   | The ref of the input's `<textarea>`, set by `TextareaComposer`. Use it to focus the input.                                                                                                                   |

While `recordingController.recordingState` is set, the default `MessageComposerUI` renders `AudioRecorder` in place of the input. See [Audio Recorder](https://getstream.io/chat/docs/sdk/react/v15/component-reference/voice-recording/audio-recorder/).

## Examples

### Read the cooldown

The cooldown isn't in the context. Read whether it's on with its hook:

```tsx
import { CooldownTimer, useIsCooldownActive } from "stream-chat-react";

export const ComposerFooter = () => {
  const isCooldownActive = useIsCooldownActive();

  if (!isCooldownActive) return null;

  return <CooldownTimer />;
};
```

`useIsCooldownActive()` re-renders only when the wait starts or ends; `CooldownTimer` counts the seconds itself. Both read `channel.cooldownTimer`, so they need a `Channel` or a `Thread` around them. `useCooldownRemaining()` returns the seconds left, for a countdown of your own. See [Slow mode](https://getstream.io/chat/docs/sdk/react/v15/features/channels/slow-mode/).

### Insert text and focus the input

A part that writes into the composer gets the composer from `useMessageComposerController()` and the input from `textareaRef`:

```tsx
import {
  AdditionalMessageComposerActions,
  useMessageComposerContext,
  useMessageComposerController,
} from "stream-chat-react";

export const ActionsWithGreeting = () => {
  const { textareaRef } = useMessageComposerContext();
  const { textComposer } = useMessageComposerController();

  const greet = () => {
    textComposer.insertText({ text: "Hi there! " });
    textareaRef.current?.focus();
  };

  return (
    <>
      <button onClick={greet} type="button">
        Greet
      </button>
      <AdditionalMessageComposerActions />
    </>
  );
};
```

Register it as `AdditionalMessageComposerActions` with `WithComponents`. It renders the default part too, so the emoji picker stays.

## Hooks

- [`useMessageComposerContext`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/composer-hooks/#usemessagecomposercontext) returns this context.
- [`useMessageComposerController`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/composer-hooks/#usemessagecomposercontroller) returns the composer itself.
- [`useMessageComposerBindings`](https://getstream.io/chat/docs/sdk/react/v15/reference/hooks/composer-hooks/#usemessagecomposerbindings) creates `textareaRef`, `onPaste` and `recordingController`, for a replacement of `MessageComposer` itself.

---

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