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>;
}