Skip to main content

Deprecated | State

warning

The state API is deprecated in favor of the simpler, more powerful page.update() API. We recommend all users migrate to the new API as soon as possible, but we will continue to support state indefinitely for backwards compatibility.

Easily create reactive apps by using state, which is a key-value store that allows you to store data that will update the UI when it changes.

Anytime you reassign the value of a key in the state object, or add a new key, Compose will automatically re-render the UI to reflect the changes

import { Compose, Page, UI } from "@composehq/sdk"

function handler({ page, ui, state }: { page: Page, ui: UI, state: State }) {
state.count = 0;

page.add(() => ui.stack([
ui.header(`Count: ${state.count}`),
ui.button("increment-btn", {
label: "Increment",
onClick: () => state.count += 1
}),
]))
}

const app = new Compose.App({ name: "Counter", handler })

Common pitfalls

When working with objects, you need to reassign the variable itself rather than just modifying a nested property for Compose to detect the change.

import { Compose, Page, UI, State } from "@composehq/sdk"

function handler({ page, ui, state }: { page: Page, ui: UI, state: State }) {
state.data = { count: 0 };

function onClick() {
// This won't work
state.data.count += 1

// Do this instead
state.data = { ...state.data, count: state.data.count + 1 }
}

page.add(() => ui.stack([
ui.json(state.data),
ui.button("increment-btn", {
label: "Increment",
onClick
}),
]))
}

const app = new Compose.App({ name: "Counter", handler })

Merge state

You can merge new state into the old object using the reserved merge key, which allows you to easily update multiple keys at once.

import { Compose, Page, UI, State } from "@composehq/sdk"

function handler({ page, ui, state }: { page: Page, ui: UI, state: State }) {
state.email = "n/a";
state.name = "n/a";

function onSubmit(formData: Record<string, any>) {
state.merge({
email: formData.email,
name: formData.name,
})
}

page.add(() => ui.form(
"form",
[ui.textInput("email"), ui.textInput("name")],
{ onSubmit }
))

page.add(() => ui.stack([
ui.header("Current response:"),
ui.text(state.email),
ui.text(state.name),
]))
}

const app = new Compose.App({ name: "Form", handler })

Overwrite state

You can overwrite the entire state object using the reserved overwrite key. This will replace the entire state object with the new object you provide.

We mainly recommend using merge to update the state, but overwrite can be useful in certain situations, like when you want to create the initial state object.

import { Compose, Page, UI, State } from "@composehq/sdk"

function handler({ page, ui, state }: { page: Page, ui: UI, state: State }) {
state.overwrite({
email: "n/a",
name: "n/a",
})

function onSubmit(formData: Record<string, any>) {
state.merge({
email: formData.email,
name: formData.name,
})
}

page.add(() => ui.form(
"form",
[ui.textInput("email"), ui.textInput("name")],
{ onSubmit }
))

page.add(() => ui.stack([
ui.header("Current response:"),
ui.text(state.email),
ui.text(state.name),
]))
}

const app = new Compose.App({ name: "Form", handler })