Run code automatically when signals change. Built-in cleanup. Simpler than useEffect!
useSignalEffect()Click the buttons and watch the effect logs appear automatically!
const [count, setCount] = useSignal(0);useSignalEffect(() => {
console.log('Count is:', count);
});💡 It auto-tracks that it depends on count - no array needed!
setCount(5); // Effect runs! ✨import { useSignal, useSignalEffect } from 'signalforge/react';
function TimerComponent() {
const [seconds, setSeconds] = useSignal(0);
// Effect runs when seconds changes
useSignalEffect(() => {
console.log(`Timer at: ${seconds} seconds`);
// Optional: Return cleanup function
return () => {
console.log(`Cleaning up timer at ${seconds}`);
};
});
// Another effect - can have multiple!
useSignalEffect(() => {
if (seconds >= 10) {
alert('Timer reached 10 seconds!');
}
});
return (
<div>
<h2>{seconds} seconds</h2>
<button onClick={() => setSeconds(seconds + 1)}>
Add Second
</button>
</div>
);
}
// ✨ No dependency array needed!
// ✨ Auto-tracks what you use
// ✨ Cleanup runs before next effectuseSignalEffect(() => {
fetchUser(userId);
});useSignalEffect(() => {
analytics.track(page);
});useSignalEffect(() => {
const id = setInterval(fn, 1000);
return () => clearInterval(id);
});useSignalEffect(() => {
localStorage.setItem('user', JSON.stringify(user));
});When your effect returns a function, it gets called before the next effect runs or when the component unmounts.
useSignalEffect(() => {
// 1. Set up resources
const subscription = api.subscribe(userId);
const timer = setInterval(() => {...}, 1000);
// 2. Return cleanup function
return () => {
subscription.unsubscribe(); // Clean up!
clearInterval(timer); // Prevent memory leaks!
};
});Master effects? Try these advanced demos: