Skip to content

Interface state

Which tab is open, whether a panel is collapsed: state your interface owns is held in cells, each with a value and a setter.

useState takes an initial value and returns the value and its setter:

src/updates.ts2
const [n, setN] = useState(0);
src/updates.ts2
<layer x={100} y={0} w={92} h={22} onClick={() => { setN(n + 1); }}>

A useState(0) is per instance: a component drawn twice has two cells.

Declare the cell once at the top level of a file, and every component that reads it shares it:

src/shop.ts2
const openTab = sessionState(0);
…
const ShopTabs = (): Component => {
const [tab, setTab] = useState(openTab);
…
const ShopContents = (): Component => {
const [tab] = useState(openTab);

Export the declaration to share it across files. A sessionState lasts until the player logs out.

persistedState saves a value on the player’s device:

src/settings.ts2
const roofRemoval = persistedState(1, 'docs.settings.roofs');

The second argument is a key. You can rename the variable freely, but changing the key declares a new setting and orphans every saved value under the old one.

useState(0)sessionStatepersistedState
Declaredat the call siteat the top of a fileat the top of a file
Sharedno, one per instanceyesyes
Holdsa whole numbera number or a stringa number or a string
Lastswhile the component existsuntil logoutacross restarts, on that device

Start with useState(0). Move to sessionState when a second component needs the value, and to persistedState when the player would miss it tomorrow.

A private cell holds a whole number; a boolean is 0 and 1. A string needs a top-level declaration:

src/menu.ts2
const lastChoice = sessionState('');
src/menu.ts2
const [chosen, setChosen] = useState(lastChoice);

Compare a string by its length, or use it in a template.

A setter can be called from a handler, a function a handler calls, or another component:

src/settings.ts2
const restoreDefaults = (): void => {
const [, setRoofs] = useState(roofRemoval);
const [, setShiftDrop] = useState(shiftClickDrop);
…
setRoofs(1);
setShiftDrop(0);

A handler’s reads are the values when it runs. If it derives several writes from one value, read it once at the top and use the local.