Component State Hooks
Component State Hooks
Developer Agent Kit — documentation written for AI agents, readable by humans.
All hooks are used inside the interactive phase (the withInteractive constructor function). They provide reactive state management for client-side behavior.
createSignal
Creates a reactive getter/setter pair:
import { createSignal } from '@jay-framework/component';
const [count, setCount] = createSignal(0);
// Read
count(); // 0
// Write
setCount(5); // set to 5
setCount((n) => n + 1); // increment
Can initialize from a getter (reactive dependency):
const [label, setLabel] = createSignal(() => 'Hello ' + props.name());
createPatchableSignal
Creates a signal with JSON Patch support for fine-grained updates to complex objects:
import { createPatchableSignal } from '@jay-framework/component';
import { REPLACE } from '@jay-framework/json-patch';
const [data, setData, patchData] = createPatchableSignal({
label: 'Hello',
count: 0,
nested: { value: 42 },
});
// Patch a specific field
patchData({ op: REPLACE, path: ['label'], value: 'Updated' });
// Patch nested field
patchData({ op: REPLACE, path: ['nested', 'value'], value: 99 });
See component-data.md for more on immutable data and patching.
createMemo
Creates a memoized computed value that recalculates only when dependencies change:
import { createMemo } from '@jay-framework/component';
const fullName = createMemo(() => `${firstName()} ${lastName()}`);
// Read
fullName(); // recomputes only when firstName() or lastName() change
With initial value:
const total = createMemo((prev) => prev + latestValue(), 0);
createEffect
Registers a side effect that runs on mount and when dependencies change. Optional cleanup function:
import { createEffect } from '@jay-framework/component';
createEffect(() => {
const handler = () => setWindowWidth(window.innerWidth);
window.addEventListener('resize', handler);
return () => window.removeEventListener('resize', handler); // cleanup
});
Effects track reactive dependencies automatically:
createEffect(() => {
document.title = `${count()} items`; // reruns when count() changes
});
createDerivedArray
Efficiently maps an array with smart caching. Only remaps items that actually changed:
import { createDerivedArray } from '@jay-framework/component';
const displayItems = createDerivedArray(
() => products(),
(item, index, length) => ({
name: item().name,
displayPrice: formatPrice(item().price),
isLast: index() === length() - 1,
}),
);
// Read the mapped array
displayItems();
Key optimizations:
- Reuses mapped items when the source item hasn't changed
- Only tracks
index()andlength()if you actually call them - Uses object identity (not deep equality) for cache hits
createEvent
Creates an event emitter for component-to-parent communication:
import { createEvent } from '@jay-framework/component';
const onChange = createEvent<{ value: number }>((emitter) => {
emitter.emit({ value: count() });
});
useReactive
Gets the current reactive context for advanced use cases:
import { useReactive } from '@jay-framework/component';
const reactive = useReactive();
Most components won't need this — prefer the higher-level hooks above.
About this document
This page is part of the Jay Stack Agent Kit — documentation generated from the framework source and written primarily for AI agents. The language and structure are optimized for machine consumption — expect precise, specification-style prose rather than narrative documentation. Learn more about the Agent Kit →