Why don't two useChat hooks with same ID share state?
two useChat usage, sharing the same id, don't use the same state/store?
Now I have enough understanding. Let me summarize the findings:
##Answer: No, two useChat calls sharing the same id do NOT share state
Looking at the source code, here's why:
###How useChat works:
-
Each
useChatcreates its ownChatinstance viauseRef:// packages/react/src/use-chat.ts, line 98-100 const chatRef = useRef<Chat<UI_MESSAGE>>( 'chat' in options ? options.chat : new Chat(optionsWithCallbacks), ); -
The
idis just an identifier stored on each instance - it's not used for looking up or sharing state:// packages/ai/src/ui/chat.ts, line 195 this.id = id; -
State is local to each
Chatinstance - eachChathas its ownReactChatStatethat holds messages, status, and error:// packages/react/src/chat.react.ts export class Chat<UI_MESSAGE extends UIMessage> extends AbstractChat<UI_MESSAGE> { #state: ReactChatState<UI_MESSAGE>; // <-- private state per instance -
The
idis only used for recreation logic: If theidoption changes, theuseChathook will create a newChatinstance (line 103-104):const shouldRecreateChat = ('chat' in options && options.chat !== chatRef.current) || ('id' in options && chatRef.current.id !== options.id);
###How to share state between components:
If you want two components to share the same chat state, you have two options:
-
Pass the same
Chatinstance via thechatoption:const chat = useMemo(() => new Chat({ id: 'my-chat' }), []); // Component A const chatA = useChat({ chat }); // Component B const chatB = useChat({ chat }); -
Lift state up and pass messages/handlers as props to child components.
The id is primarily useful for:
- Identifying which chat a stream belongs to (e.g., for resuming streams)
- Persistence/storage identification
- Not for automatic state sharing between hook instances
END OF POST