Skip to main content

Editor hooks and state

You've written an editor shell. Now you need to actually read the document and change it. Powerhouse gives you a small set of hooks from @powerhousedao/reactor-browser to do exactly that — no manual subscriptions, no wiring.

The hook you'll use 90% of the time

Codegen produces a typed hook for your document model. For a TodoList model, that's useSelectedTodoListDocument. Call it at the top of your editor:

const [doc, dispatch] = useSelectedTodoListDocument();

doc is a fully-typed PHDocument<TodoListState>. Read state off doc.state.global or doc.state.local. The component re-renders automatically whenever an operation lands — you never poll.

dispatch sends actions into the Reactor:

dispatch(addTodo({ id: generateId(), title: "Buy milk" }));

Always generate IDs before calling dispatch — reducers must stay pure.

When the document type isn't known at compile time

Sometimes you're building a generic component that works across models. Two hooks cover that:

  • useSelectedDocument() — returns [PHDocument, DispatchFn], untyped. Throws if nothing is selected.
  • useSelectedDocumentOfType(type) — same shape, but narrows to a specific type string. Throws if the selected document is a different type.

Use the generated typed hook whenever you can. Fall back to these only when generics genuinely prevent it.

Loading a document by ID

Need a document that isn't the currently selected one? Two options:

  • useDocumentById(id) — returns [PHDocument | undefined, DispatchFn]. The doc is undefined while loading; render a spinner in that case.
  • useDocument(id) — Suspense-based. It never returns undefined; instead it suspends until the document is ready. Wrap the caller in <Suspense>.
QuizYour editor has a button. When clicked, it should mark a todo as done. Which hook gives you what you need?

The dispatch signature

Every hook's dispatch has the same shape:

dispatch(
actionOrActions: TAction | TAction[] | undefined,
onErrors?: (errors: Error[]) => void,
onSuccess?: (result: PHDocument) => void,
): void

Pass a single action or an array to batch. Use onErrors to surface validation failures in your UI. Use onSuccess if you need the updated document immediately after the operation lands.