Referencing components with refs
A ref is a handle to a component. With one, a handler can change, move or measure a component other than the one that was clicked.
Declaring and binding
Section titled “Declaring and binding”Call useRef() to get a ref, and bind it with the ref prop:
export const QuestList = (): Component => { const list = useRef(); // … <layer ref={list} x={2} y={2} w={{ fill: 22 }} h={{ fill: 4 }} scrollHeight={QUESTS.length * ROW_H}> {/* … */} <Scrollbar content={list} />At module scope, declare a ref with a name:
const plate = createRef('docs-marker:plate');createRef names one component in the project, and can be exported and named
by another interface. Use useRef() in a component drawn several times.
Changing a component
Section titled “Changing a component”Assigning to a ref’s property changes that component. A position goes through
props, as a pair:
if (mode === 0) { target.props = { x: 'left', y: 'center' }; }if (mode === 1) { target.props = { x: 'center', y: 'center' }; }if (mode === 2) { target.props = { x: 'right', y: 'center' }; }{ w, h } is the other pair. ref.x = n nudges by pixels:
onOptionSelect={(event) => { // … event.self.x = event.self.x + 8; report(event.self, readout);ref.options writes the right-click menu, the same list the options prop
takes; [] clears it.
Measuring a component
Section titled “Measuring a component”Eight properties can be read as well as written, and give the values after layout:
ref.width, ref.height | the size after layout |
ref.x, ref.y | the position after layout |
ref.scrollX, ref.scrollY | the current scroll offset |
ref.scrollWidth, ref.scrollHeight | the scrollable extent |
The scrollbar sizes its thumb from the list it was handed:
<sprite ref={thumb} y={ARROW} w="fill" h={Math.max( MIN_THUMB, extent > 0 ? (bar.height - ARROW * 2) * content.height / extent : bar.height - ARROW * 2, )}Binding a handler through a ref
Section titled “Binding a handler through a ref”A handler can be assigned through a ref. The scrollbar puts the wheel handler on the list it scrolls, so the player scrolls by pointing at the list:
content.onScrollWheel = (event) => { content.scrollY = content.scrollY + event.mouseY * WHEEL; trackScroll(gutter, thumb, capTop, capBottom, content);};content.onScrollWheel = null takes it off again.
A ref travels down
Section titled “A ref travels down”A ref is an ordinary value: a component takes one as a prop, a plain function as an argument. A module-scope ref goes down as a constant:
<MoveButton label="Left" mode={0} x={0} target={plate} readout={readout} />A ref you were handed is for reading and writing through; the component that created it binds it.
When two components need to affect each other, the component that renders both holds the ref and passes it down.
When a ref write is not enough
Section titled “When a ref write is not enough”A ref write lasts until the markup sets that prop again. A change that must
last is state, read in the markup. The reference has
useRef,
createRef, and the ref properties
under Types.