Skip to content

useServerStateOnce

useServerStateOnce reads a value the server owns as the component builds and subscribes to nothing: the panel shows the value as it was when it opened.

useServerStateOnce(ref: ServerRef): Int
useServerStateOnce(body: () => Int): Int
useServerStateOnce(body: () => Boolean): Boolean
src/once.ts2
export const PoisonThenAndNow = (): Component => {
const atOpen = useServerStateOnce(Varps.POISON);
const now = useServerState(Varps.POISON);
  • ref: A Varps.*, Varbits.* or Skills.* reference, as for useServerState.

The value at build time, typed as the reference says — an Int, or the type a variable is declared to hold.

The second form takes an arrow — useServerStateOnce(() => tierFacts(tier)) — for a value computed from several reads at build time.

  • body: An expression. Every read inside it is untracked — a variable, a skill, a cell, and everything a called function reads. It need not be a single call.

The expression’s value at build time.

  • It re-reads when the component is rebuilt, e.g. the interface reopens. A setter, new props or another read’s redraw do not re-read it. A prop the body read is the prop at build time.
  • There is no setter. If the panel needs its own editable copy, seed a cell: useState(useServerStateOnce(V)).
  • A seeded cell with its setter dropped is refused (TS2E239). Drop the useState and use the value.
  • Inside a render body only (TS2E236). Write useServerState there.
  • No subscribing hook inside the body (TS2E237). useState, useWatch, useDerived, useInventory, useOnResize, useRerenderOn and a nested once are refused. A useServerState inside the body is allowed.
  • Not inside a .map() row (TS2E238). Make the row a component.
refused/use-server-state-once.ts2
const [poison] = useState(useServerStateOnce(Varps.POISON)); // no setter: drop the useState

Showing a value as it was when the panel opened

Section titled “Showing a value as it was when the panel opened”
src/once.ts2
<Reading label="Poison on open" value={`${atOpen}`} color={Colors.WHITE} y={0} />
<Reading label="Poison now" value={`${now}`} color={now === atOpen ? Colors.WHITE : Colors.GREEN} y={ROW_H} />
src/once.ts2
export const StaminaChoice = (): Component => {
const [stamina, setStamina] = useState(useServerStateOnce(Varbits.STAMINA_ACTIVE));

A bar that remembers where the fight began

Section titled “A bar that remembers where the fight began”
src/idiomatic.ts2
const maxAtOpen = useServerStateOnce(HudVarbits.MAX_HP);

If the panel should follow the value, read it with useServerState.

The value updated when I did not expect it to

Section titled “The value updated when I did not expect it to”

Something rebuilt the component.

You dropped the setter. If nothing will ever write the cell, you do not need one: use the read-once value directly.