Skip to content

ChannelActionContext

ChannelActionContext is provided by Channel and exposes action handlers for the active channel. Access it with useChannelActionContext.

Best Practices

  • Use context actions instead of calling client APIs directly to keep UI state in sync.
  • Wrap action calls in user-initiated events to avoid accidental side effects.
  • Prefer jumpToFirstUnreadMessage/jumpToLatestMessage for navigation to keep list state consistent.
  • Treat markRead as the single source of read-state updates to avoid double-counting.
  • Debounce or throttle custom action triggers to prevent rapid re-queries.

Basic Usage

Pull values from ChannelActionContext with our custom hook:

const { closeThread, loadMoreThread } = useChannelActionContext();

Values

Value Description Type
closeThread Closes the currently open Thread. (event?: React.BaseSyntheticEvent) => void
deleteMessage Triggers the delete-message request. (message: LocalMessage, options?: DeleteMessageOptions) => Promise<void>
dispatch Dispatch function for the ChannelStateReducer. ChannelStateReducerAction
editMessage Updates a message and returns a promise. (message: LocalMessage | MessageResponse, options?: UpdateMessageOptions) => Promise<UpdateMessageAPIResponse | void>
jumpToFirstUnreadMessage Jumps to the first unread message. If not found locally, it can query around that message using queryMessageLimit. Falls back to the last read message when available. (queryMessageLimit?: number) => Promise<void>
jumpToLatestMessage Restores the list to the most recent messages after jumpToMessage. () => Promise<void>
jumpToMessage Scrolls to the message with the given messageId. (messageId: string) => Promise<void>
loadMore Loads the next page of messages. (limit?: number) => Promise<number>
loadMoreNewer Loads newer messages. (limit?: number) => Promise<number>
loadMoreThread Loads the next page of thread messages. () => Promise<void>
markRead Throttled function that marks the channel read and updates local state. Accepts optional MarkReadWrapperOptions; updateChannelUiUnreadState defaults to true. (options?: MarkReadWrapperOptions) => void
onMentionsClick Runs when an @mention is clicked and receives the DOM event, the matched user for direct user mentions, and the message metadata. (event: React.BaseSyntheticEvent, user?: UserResponse, message?: LocalMessage) => void
onMentionsHover Runs when an @mention is hovered and receives the DOM event, the matched user for direct user mentions, and the message metadata. (event: React.BaseSyntheticEvent, user?: UserResponse, message?: LocalMessage) => void
openThread Opens a thread for the parent message, optionally with the click event. (message: LocalMessage, event?: React.BaseSyntheticEvent) => void
removeMessage Removes a message from MessageList. (message: LocalMessage) => void
retrySendMessage Resends a message. (message: LocalMessage) => Promise<void>
sendMessage Sends a message on Channel. Takes a single params object with the optimistic localMessage, the message payload, and optional send options. (params: { localMessage: LocalMessage; message: Message; options?: SendMessageOptions }) => Promise<void>
updateMessage Updates a message on Channel. (message: LocalMessage) => void

Examples

Jump to a searched message

const JumpToMessage = () => {
  const { jumpToMessage } = useChannelActionContext();
  return (
    <button
      onClick={async () => {
        // the filtering based on channelId is just for example purposes.
        const results = await chatClient.search(
          { id: { $eq: channelId } },
          "Message 29",
          { limit: 1, offset: 0 },
        );

        jumpToMessage(results.results[0].message.id);
      }}
    >
      Jump to message 29
    </button>
  );
};

// add the JumpToMessage to the component tree as a child of `Channel`
return (
  <Channel channel={channel}>
    <JumpToMessage />
    <Window>
      <MessageList />
    </Window>
  </Channel>
);