← Back to Home

⚡ Effects - React to Changes

Run code automatically when signals change. Built-in cleanup. Simpler than useEffect!

What Are Effects?

Effects are actions that happen automatically when a signal changes. Like setting up a "watcher" that says "whenever this changes, do that!"

💡 Real-life example: Like a motion sensor light! When it detects movement (signal changes), it automatically turns on the light (effect runs). No manual switch needed!

💡

Why Use Effects?

Because you need to do things WHEN state changes: save to server, log analytics, start timers, etc.

❌ React useEffect Problems

useEffect(() => {
  // What dependencies?? 🤔
  console.log(count, name);
}, [count, name]); // Easy to forget!
//  ↑ Manual tracking = BUGS

// Forgot to add 'name' to array?
// Effect won't run when name changes!
  • • Manual dependency arrays
  • • Easy to forget dependencies
  • • Linter warnings everywhere

✅ SignalForge Effects

useSignalEffect(() => {
  // Auto-tracks EVERYTHING! ✨
  console.log(count, name);
}); // No dependency array!

// Automatically knows count and name
// are dependencies. No manual work!
  • • Auto-tracks all signals used
  • • Impossible to forget deps
  • • No linter warnings!
🚀

How To Use It? (Pattern + Real Examples!)

📝 Basic Pattern

useSignalEffect(() => {
  // Code here runs when ANY signal used inside changes
  console.log('Count changed to:', count);
  
  // Optional cleanup (runs before next effect)
  return () => {
    console.log('Cleaning up!');
  };
});

💾 Example: Auto-save

useSignalEffect(() => {
  localStorage.setItem(
    'draft', 
    draftText
  );
});

📊 Example: Analytics

useSignalEffect(() => {
  analytics.track(
    'page_view',
    { page: currentPage }
  );
});

⏰ Example: Timer

useSignalEffect(() => {
  const id = setInterval(
    () => tick(), 1000
  );
  return () => clearInterval(id);
});

🌐 Example: API Call

useSignalEffect(() => {
  fetch(`/api/${userId}`)
    .then(r => r.json())
    .then(setUserData);
});

🎮 Watch Effects Run Automatically!

Every time you change the counter, the effect logs it automatically ⬇️

0

Effect Logs

No logs yet. Change the counter to trigger effects.

🚀 How It Works (3 Simple Steps)

Step 1: Create your signals
const [count, setCount] = useSignal(0);
Step 2: Create an effect that uses the signal
useSignalEffect(() => {
  console.log('Count is:', count);
});

💡 It auto-tracks that it depends on count - no array needed!

Step 3: Change the signal - effect runs automatically!
setCount(5); // Effect runs! ✨

💻 Complete Code Example

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 effect

💡 Why SignalForge Effects Are Better

❌ Traditional useEffect:
  • • Must manually list dependencies
  • • Easy to forget a dependency
  • • Stale closures are common bugs
  • • Runs on every render initially
  • • Verbose and error-prone
✅ SignalForge useSignalEffect:
  • • Auto-tracks dependencies
  • • Impossible to miss dependencies
  • • No stale closure issues
  • • Only runs when signals change
  • • Clean, simple syntax

🌍 Real-World Use Cases

📡 API Calls
Fetch data when user ID changes
useSignalEffect(() => {
  fetchUser(userId);
});
📊 Analytics Tracking
Log page views or events
useSignalEffect(() => {
  analytics.track(page);
});
⏰ Timers & Intervals
Set up timers with auto-cleanup
useSignalEffect(() => {
  const id = setInterval(fn, 1000);
  return () => clearInterval(id);
});
💾 LocalStorage Sync
Save state to localStorage
useSignalEffect(() => {
  localStorage.setItem('user', JSON.stringify(user));
});

🧹 Understanding Cleanup Functions

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!
  };
});
💡 Pro tip: Always clean up subscriptions, timers, and listeners to prevent memory leaks!

🎓 Next Steps

Master effects? Try these advanced demos: