The state: a JSON object. Values that JSON cannot hold
(functions, undefined, Date, Map, ...) do not come back as they were.
Declare it with type, not interface: TypeScript does not accept an
interface as a Record<string, unknown> unless it has an index signature.
The connected App instance, or null during initialization
State to use until, and unless, saved state is found
The current state and a function to change it, as useState does
type Draft = { version: 1; text: string };
const EMPTY_DRAFT: Draft = { version: 1, text: "" };
function MyApp() {
const { app } = useApp({
appInfo: { name: "MyApp", version: "1.0.0" },
capabilities: {},
});
const [saved, setDraft] = useViewState<Draft>(app, EMPTY_DRAFT);
// The saved state may come from an older version of this View
const draft = saved.version === 1 ? saved : EMPTY_DRAFT;
return (
<textarea
value={draft.text}
onChange={(e) => setDraft({ ...draft, text: e.target.value })}
/>
);
}
App.setViewState for the underlying methoduseApp for the hook that provides app
React hook that keeps a piece of state and saves it with the host, so that it comes back the next time the View is rendered (for example after a reload, or in a reopened conversation).
It works like
useState. The state starts asinitial; onceappis connected, it becomes the state that the host has saved for this View, if any (viewStateinApp.getHostContext). Each call of the setter changes the state at once and, afterdebounceMswithout another change, saves it withApp.setViewState.viewStatecapability, nothing is saved and the hook behaves like plainuseState.maxBytes) is reported withconsole.warnand otherwise ignored; the state on screen is kept, and the next change is saved as usual.appis connected are kept: they win over the state that the host has saved, and are saved onceappis connected.apphas been closed), so that the last change is not lost. If the host removes the View before the wait is over, that change is lost.One hook per View. A save replaces everything that is saved for the View, so two
useViewStatehooks on the sameappwould overwrite each other. Keep all the state to save in one object, in one hook. For the same reason, do not mix this hook with your own calls ofApp.setViewState.Version and check the state. The saved state may have been written by an older version of your View. The hook cannot check it against
T: it returns what the host saved as it is. Put a version in the state, and check it before you use the state, as the example below does.