useViewState is a drop-in useState that fixes both.
Example
A carousel persists the shopper’s sort choice across remounts, and the model sees it on the next turn.Type Parameters
T
T is inferred from defaultState; set it explicitly only when defaultState is omitted or null.
Parameters
defaultState
state is never null; omit it, or pass null, and state is null until the first write. When the host already has persisted state, that value wins and defaultState is ignored.
Returns
useViewState returns a readonly [state, setState] tuple, the same ergonomics as useState.
state
DataLLM is stripped before it reaches your component.
setState
(prev) => next, exactly like React’s useState setter. When defaultState is omitted the type widens to SetStateAction<T | null>, so the setter also accepts null. The new value is written through to the host right away, then reflected back into state on the next render.
Lifecycle
Persistence. View state belongs to a single view instance, the view one tool call rendered. It survives that instance’s re-renders, remounts, and display-mode changes, and a closed and reopened conversation remounts the instance with its previous state. A different tool invocation gets its own state, starting fromdefaultState.
Model visibility. When a view has several instances, the model typically sees just one, whichever updated its state most recently. On ChatGPT, a PiP or fullscreen view always pushes updates to the model, but an inline view pushes only right after it mounts, before any conversation turn, so an inline view’s later updates may not reach the model.
Durability. View state is best-effort, not durable storage. On Claude, older state can be evicted as other views accumulate, so a view may reopen to its defaultState.
Manage State
Decide what to persist and share with the model
DataLLM
Narrate the on-screen state to the model
useToolInfo
Read the tool result the view mounted with