Skip to content

Watching and reacting

Reading a value redraws the component when the value moves. A watch runs a handler instead, and redraws nothing.

useServerState(X) makes the render depend on X:

src/watch.ts2
const poison = useServerState(Varps.POISON);

useWatch(X, handler) runs the handler when X moves, and the handler writes the label:

src/watch.ts2
useWatch(Varps.POISON, (event) => { writePoison(event.component); }, poisonLabel);
src/watch.ts2
const writePoison = (into: ComponentId): void => {
const poison = useServerState(Varps.POISON);
into.text = poison > 0 ? `Poison: ${poison}` : 'Poison: none';
};

Call the same function from onLoad so the label is right before the value first moves:

src/watch.ts2
onLoad={(event) => { writePoison(event.self); }} />

A watch handler may call a setter, for something a read cannot show, such as how often the value moved:

src/watch.ts2
const [changes, setChanges] = useState(0);
useWatch(Varps.POISON, () => { setChanges(changes + 1); });

One source, or a list of sources of one kind: game variables, skills, inventories, or the client’s occasions below. useWatch([A, B], handler) watches both; write one useWatch per kind.

A watch is bound on a host, the component’s own root unless the third argument names another. Bind it on the label it rewrites, named with createRef:

src/watch.ts2
const poisonLabel = createRef('docs-watch:poison');

A watch under a hide does not fire; see Timers.

The client announces ten things that are not values. Engine names them, and a watch can wait for each:

fires when
Engine.SUB_CHANGEany sub-interface opens or closes, anywhere
Engine.DIALOG_ABORTthe server aborts the current dialogue
Engine.CONTENT_CHANGEthe client’s content changes
Engine.CHATa chat message arrives
Engine.FRIENDSthe friend list moves
Engine.CLANthe friends-chat channel moves
Engine.CLAN_SETTINGSclan settings move
Engine.CLAN_CHANNELthe clan channel moves
Engine.MISCthe client’s miscellaneous update runs
Engine.STOCKthe Grand Exchange offers move

The handler receives only event.component and reads whatever it needs.

A handler can set a text, a colour or a hide, but it cannot add or remove a component. When the change is to what exists, redraw instead:

  • useRerenderOn(occasion, host?) redraws the component when the client announces occasion.
  • useOnResize(ref) redraws the component when the game window resizes ref.
what happens
useWatch(X, handler)your handler runs
useRerenderOn(X)the whole render runs again

The reference has a page for each: useWatch, useRerenderOn, useOnResize and the ten occasions under Engine.