NodeHandle
A ref on a drawing node: changes a mounted node without a React render.
const box = useNode()
<Rect ref={box} x={0} y={0} width={40} height={40} />
box.set({ x: 120 })A prop the program keeps a value slot for is patched in place: one
setValues, no re-encode, and it works inside a worklet, so a gesture can
drive it without ever waking the JS thread. That covers the geometry props
(x, y, width, height, cx, cy, r, rx, ry, x1, y1, x2,
y2), strokeWidth, strokeMiter, opacity, fontSize, visible,
color, the paint enums (style, strokeCap, strokeJoin, blendMode,
antiAlias), image and rect, a <Group>'s transform operands, a
<Shader>'s uniforms, a gradient's geometry / positions / colors, a
filter's parameters, and text / path content (string slots, re-shaped or
re-parsed on the render thread). A prop with no slot re-encodes the scene -
still with no React render, no reconciler commit and no Fabric commit - and
from a worklet it hops to the JS thread to do it.
Most of the non-geometry props are made live by the first write, not by the
ref: each costs the render thread work every frame, so that write
re-encodes once and every one after it is a slot patch. A ref on a
<Shader> has no other job, so its uniforms are live from the first
compile. A handle keeps at most 16 gradient stops (longer imperative writes
are truncated) and 32 uniform floats (uniforms outside that pool re-encode).
Docs: docs/content/docs/imperative.mdx.
The next React commit wins. An imperative write survives until the canvas re-renders, and then the JSX props are the truth again. Drive a value from one side or the other, not both.
Methods
set()
set(props: Record<string, unknown>): void;Parameters
props
Record<string, unknown>
Returns
void