Skip to content

Components

A Sygnal component is a function with optional static properties attached to it. At minimum, a component is just a function that returns JSX:

function MyComponent() {
return <div>Hello World</div>
}

To make a component interactive, attach .initialState, .intent, and .model properties:

function Counter({ state }) {
return (
<div>
Count: {state.count}
<button className="btn">+1</button>
</div>
)
}
Counter.initialState = { count: 0 }
Counter.intent = ({ DOM }) => ({
INCREMENT: DOM.select('.btn').events('click')
})
Counter.model = {
INCREMENT: (state) => ({ ...state, count: state.count + 1 })
}
PropertyTypeDescription
.initialStateObjectThe starting state for the component
.intentFunctionMaps driver sources to named action streams
.modelObjectDefines what happens for each action
.calculatedObjectDerived state fields computed from base state
.contextObjectValues passed down to all descendants
.usesObjectBehaviors this component uses, each under a state key
.onErrorFunctionError boundary handler — receives (error, { componentName }), returns fallback VNode
.isolatedStateBooleanRequired when a sub-component has .initialState (prevents accidental parent state overwrite)
.debugBooleanEnable debug logging for this component
.componentNameStringThe component’s name in diagnostics, devtools and uid() (default: the function’s name)

The table lists the most common statics. Sygnal also reads connections, resources, route, head and timers, so these names, like the ones above, are reserved: don’t use them for statics of your own.

The component function is the view. It receives a single object where props from the parent are spread at the top level alongside state, children, and context:

function MyComponent({ state, className, children, context }) {
return (
<div className={className}>
<h1>{state.title}</h1>
{children}
</div>
)
}
ParameterDescription
stateThe current component state
childrenChild elements passed between the component’s opening and closing tags
slotsNamed content regions passed with <Slot> (see Slots)
contextValues from ancestor components’ .context definitions
uiduid(name?) returns a stable id string unique to this component instance, for id / for / aria-* (see Forms)
Individual propsProps from the parent (e.g., title, className) are spread at the top level

Props are not nested under a props key. If a parent renders <MyChild title="Hello" />, the child destructures title directly: function MyChild({ title, state }) { ... }.

The view function must be pure: it should only use the values it receives to produce virtual DOM. Never perform side effects (API calls, direct DOM manipulation, etc.) inside the view.

Always read everything from the first argument: it is the only one (6.0 removed the positional (props, state, context) arguments; see Migrating to 6.0).

Because the view’s argument also carries state, children, slots, context and uid, a parent prop with one of these names is overwritten (Sygnal warns with SYG106, an error in strict mode). The state prop is special: it selects the child’s state slice. Name data props something else, such as item or contextValue.