useTree

Open in

Provide stable structural query callbacks backed by the transport's conversation tree. These are thin useCallback wrappers around the tree's query methods. The hook does not re-render on tree changes — use useView when you want a reactive subscription. Reach for useTree when you need to query tree structure inside an event handler or a memoised computation without subscribing to every update.

This hook must be used within a TransportProvider or a ChatTransportProvider.

React

1

2

3

4

5

6

7

import { useTree } from '@ably/ai-transport/react';

function BranchNav({ messageId }) {
  const { getSiblings, hasSiblings } = useTree();
  if (!hasSiblings(messageId)) return null;
  return <Arrows siblings={getSiblings(messageId)} />;
}

Parameters

transportoptionalClientTransport<TEvent, TMessage>
Transport to read tree structure from. Defaults to the nearest provider when omitted.

Returns

TreeHandle<TMessage>

getSiblingsFunction
(msgId: string) => TMessage[]. Get every sibling message at a fork point, ordered chronologically by serial.
hasSiblingsFunction
(msgId: string) => boolean. Whether a message has sibling alternatives.
getNodeFunction
(msgId: string) => MessageNode<TMessage> | undefined. Get a node by message ID.

The returned callbacks are stable across renders (they are useCallback-wrapped), so they are safe to use as dependencies in useEffect or useMemo without triggering rerun loops.

Example

React

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import { useTree, useView } from '@ably/ai-transport/react';
import { useMemo } from 'react';

function ConversationStats() {
  const { messages } = useView();
  const { getSiblings } = useTree();

  const branchCount = useMemo(
    () => messages.reduce((total, m) => total + getSiblings(m.id).length, 0),
    [messages, getSiblings],
  );

  return <span>Total branches: {branchCount}</span>;
}