React Integration
The @signalis/react package provides React-specific integrations for Signalis, including hooks and a Higher-Order Component for automatic re-rendering.
Key Features
reactorHOC: Automatically re-renders components when signals change- React Hooks:
useSignal,useDerived,useSignalEffectfor component-scoped reactivity - Full Core Re-export: All of
@signalis/coreis re-exported for convenience
Quick Example
import { useSignal, reactor } from '@signalis/react';
const Counter = () => {
const count = useSignal(0);
return (
<div>
<p>Count: {count.value}</p>
<button onClick={() => count.value++}>Increment</button>
</div>
);
};
export default reactor(Counter);Integration Approach
Signalis integrates with React in two ways:
1. Global Signals with reactor
Create signals outside components and use reactor to make components reactive:
import { createSignal, reactor } from '@signalis/react';
// Signal lives outside the component
const count = createSignal(0);
const Counter = () => {
return <div>{count.value}</div>;
};
export default reactor(Counter);2. Component-Local Signals with Hooks
Create signals inside components using hooks:
import { useSignal, reactor } from '@signalis/react';
const Counter = () => {
// Signal is created and persisted across renders
const count = useSignal(0);
return <div>{count.value}</div>;
};
export default reactor(Counter);Core Concepts
The reactor HOC
The reactor Higher-Order Component wraps your component in a reactive context. It tracks signals read during render and re-renders when they change. Signal reads in event handlers or callbacks are not tracked.
import { reactor } from '@signalis/react';
const MyComponent = () => {
// Component implementation
};
export default reactor(MyComponent);Important: Always wrap components with reactor if they read signal values!
Hooks for Component State
Use Signalis hooks like you would React's built-in hooks:
useSignal: LikeuseState, but returns a signaluseDerived: LikeuseMemo, but returns a derived valueuseSignalEffect: LikeuseEffect, but tracks signals automatically
React Hooks Available
useSignal
Creates a signal that persists across component re-renders.
const count = useSignal(0);
const name = useSignal(() => expensiveComputation());useDerived
Creates a derived value that persists across re-renders.
const doubled = useDerived(() => count.value * 2);
const total = useDerived(() => price.value * (1 + taxRate), [taxRate]);useSignalEffect
Creates an effect that automatically tracks signal dependencies.
useSignalEffect(() => {
console.log('Count changed:', count.value);
});Comparison with React State
Traditional React
function Counter() {
const [count, setCount] = useState(0);
const doubled = useMemo(() => count * 2, [count]);
useEffect(() => {
console.log(`Count: ${count}`);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<p>Doubled: {doubled}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}With Signalis
const Counter = () => {
const count = useSignal(0);
const doubled = useDerived(() => count.value * 2);
useSignalEffect(() => {
console.log(`Count: ${count.value}`);
});
return (
<div>
<p>Count: {count.value}</p>
<p>Doubled: {doubled.value}</p>
<button onClick={() => count.value++}>Increment</button>
</div>
);
};
export default reactor(Counter);Benefits
- Less boilerplate: No dependency arrays for signal-only dependencies
- Mutable-looking updates:
count.value++instead ofsetCount(c => c + 1) - Fine-grained reactivity: Only re-renders when used signals change
- Composability: Signals can be shared across components
- Familiar patterns: Similar to existing state management solutions
Version Requirements
- React: 19.0 or higher
- React DOM: 19.0 or higher
Next Steps
- reactor HOC - Automatic re-rendering
- useSignal - Component-local signals
- useDerived - Computed values in components
- useSignalEffect - Effects with automatic tracking
- Examples - See complete examples