Skip to content

Function: useSignalEffect()

Documentation / @xmachines/play-react / useSignalEffect

function useSignalEffect(callback): void;

Defined in: packages/play-react/src/useSignalEffect.ts:65

React hook that subscribes to signal changes and runs effect callback

Wraps Signal.subtle.Watcher to automatically track signal dependencies accessed in the callback. When any tracked signal changes, the callback re-runs and React component re-renders.

Architecture (per RESEARCH.md Pattern 3):

  • Uses Signal.Computed to wrap callback for automatic dependency tracking
  • Signal.subtle.Watcher monitors the Computed for changes
  • Microtask batching coalesces rapid signal updates
  • Forces React re-render via useReducer when signals change
  • Handles cleanup on unmount to prevent memory leaks

Invariant: Signal-Only Reactivity - Signals accessed in callback are watched. Invariant: Passive Infrastructure - React observes signals and does not control them.

Parameters

ParameterTypeDescription
callback() => void | (() => void)Effect function that accesses signals. Can return cleanup function.

Returns

void

Example

const MyComponent = ({ actor }) => {
const [view, setView] = useState(null);
// Subscribe to actor.currentView signal
useSignalEffect(() => {
const currentView = actor.currentView.get();
setView(currentView);
});
return <div>{view?.component}</div>;
};

Remarks

CRITICAL: Signals must be accessed unconditionally (no if statements). Conditional signal access breaks automatic dependency tracking.

Performance: Microtask batching (queueMicrotask) prevents React thrashing when multiple signals update rapidly. Per signal-polyfill README pattern.

Why forceUpdate: React needs useState/useReducer to trigger re-render cycle. Signal changes won’t automatically re-render React components without forcing update via state change.

Implementation note: We wrap the callback in Signal.Computed because Signal.subtle.Watcher cannot automatically track arbitrary function calls. The Computed handles dependency tracking, and the Watcher monitors it.