# Hooks

The SDK includes two hooks that make it easier to build custom AI UI components.

## Best Practices

- Use `useAIState` to avoid duplicating backend state logic.
- Keep streaming speeds readable; avoid overly fast typewriter effects.
- Prefer `useMessageTextStreaming` for AI messages only.
- Keep custom indicators simple and state-driven.
- Reset streaming when message IDs change to avoid stale text.

## `useAIState`

Returns the current AI state for the active `channel`.

## Example Usage

```tsx
const isMessageAIGenerated = (message) => !!message.ai_generated;

const MyAIStateIndicator = () => {
  const { aiState } = useAIState();
  return aiState === AIStates.Thinking ? (
    <div>
      <p>The chat-bot is currently thinking...</p>
    </div>
  ) : null;
};

const App = () => (
  <Chat client={client} isMessageAIGenerated={isMessageAIGenerated}>
    <Channel channel={channel}>
      <MessageList />
      <AIStateIndicator />
      <MessageInput />
    </Channel>
  </Chat>
);
```

In the example above, the custom indicator renders only when the AI is in the `AI_STATE_THINKING` state.

### `useMessageTextStreaming`

Returns text in a streamed, typewriter fashion. Control the speed with `streamingLetterIntervalMs` and `renderingLetterCount`.

## Example usage

```tsx
const isMessageAIGenerated = (message) => !!message.ai_generated;

const MyStreamedMessageText = ({ message: messageFromProps, renderText }) => {
  const { message: messageFromContext } = useMessageContext(
    "StreamedMessageText",
  );
  const message = messageFromProps || messageFromContext;
  const { text = "" } = message || {};
  const { streamedMessageText } = useMessageTextStreaming({
    renderingLetterCount: 1,
    streamingLetterIntervalMs: 10,
    text,
  });

  return (
    <MessageText
      message={{ ...message, text: streamedMessageText }}
      renderText={renderText}
    />
  );
};

const App = () => (
  <Chat client={client} isMessageAIGenerated={isMessageAIGenerated}>
    <Channel channel={channel} StreamedMessageText={MyStreamedMessageText}>
      <MessageList />
      <MessageInput />
    </Channel>
  </Chat>
);
```

This override uses `useMessageTextStreaming` to speed up the typewriter animation.


---

This page was last updated at 2026-03-13T13:15:44.312Z.

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