Interfaces

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

On this page