useWatch
useWatch runs a handler when a value the server owns moves — a game
variable, a skill, an inventory — or when the client announces one of its
occasions. Nothing is redrawn.
useWatch(source: WatchSource | WatchSource[], handler: Handler, on?: Ref): voidReference
Section titled “Reference”useWatch(source, handler, on?)
Section titled “useWatch(source, handler, on?)”export const PoisonWatch = (): Component => { useWatch(Varps.POISON, (event) => { writePoison(event.component); }, poisonLabel);const writePoison = (into: ComponentId): void => { const poison = useServerState(Varps.POISON); into.text = poison > 0 ? `Poison: ${poison}` : 'Poison: none';};Parameters
Section titled “Parameters”source: What to watch — aVarps.*orVarbits.*reference, aSkills.*reference, anInventories.*reference, or anEngine.*occasion. Or a list of several of one kind:useWatch([A, B], handler).handler: An ordinary handler. It is told nothing about what changed;event.componentis the component the watch is bound on.on: A ref naming the component the watch lives on — its host. Defaults to this component’s root.
Returns
Section titled “Returns”Nothing.
Caveats
Section titled “Caveats”- It redraws nothing.
- One kind per call (
TS2E218). A varbit watch fires when its containing variable moves. - A cell the handler writes and the render never reads is refused
(
TS2E228). Read the cell, or useuseRerenderOnwhen a redraw is what you wanted. - A hidden host does not fire. A watch under a
hidefires once shown. - A host scrolled out of sight does not fire until it scrolls back; put the watch on a host outside the scrolling layer.
- A
.map()row cannot call a hook (TS2E203). For a watch on each row, make the row a component. - A host in a box 0 wide or 0 tall is refused (
TS2E252); give the boxw={1} h={1}.Engine.SUB_CHANGEandEngine.DIALOG_ABORTare the exceptions. event.componentinside the handler is the host, so a handler that rewrites itself has to be bound on itself — the third argument, usually a module-scopecreateRef.- The handler’s reads are point-in-time, like any handler’s.
useServerStateinside it is a read of the moment and no subscription.
useWatch([Varps.POISON, Skills.ATTACK], () => { label.color = Colors.GREEN; }); // two kinds const [, setSeen] = useState(0); // never read useWatch(Varps.POISON, () => { setSeen(1); });Rewriting a label in place
Section titled “Rewriting a label in place”const poisonLabel = createRef('docs-watch:poison'); <text ref={poisonLabel} x="right" y="center" w={120} h={16} text="Poison: -" font={Fonts.PLAIN} align="right" valign="middle" shadow color={Colors.WHITE} onLoad={(event) => { writePoison(event.self); }} />onLoad fills the label as the interface opens; the watch updates it after.
Feeding a cell
Section titled “Feeding a cell”export const PoisonChanges = (): Component => { const [changes, setChanges] = useState(0); useWatch(Varps.POISON, () => { setChanges(changes + 1); });Naming the host
Section titled “Naming the host” useWatch(Varps.POISON, () => { const poison = useServerState(Varps.POISON); label.text = poison > 0 ? `Poison ${poison}` : 'No poison'; }, host);Watching an occasion
Section titled “Watching an occasion” useWatch(Engine.SUB_CHANGE, (event) => { writeDivider(event.component); }, label);Engine names the ten.
Troubleshooting
Section titled “Troubleshooting”My handler never fires
Section titled “My handler never fires”Look up the tree for a hide, and check the host’s box is not 0 on either
axis. Then check the source is the one that moves: a watch on a varbit fires
when the variable containing it moves.
A cell is “written but never read”
Section titled “A cell is “written but never read””Read the cell in the render, or reach for useRerenderOn if
the point was to redraw.