Effects

Effects let you run side effects when reactive state changes. Logging, DOM manipulation, API calls—anything that needs to happen because something changed.

Basic Usage

const { signal, effect } = Lightview;

const count = signal(0);

// This runs immediately, then re-runs when count changes
effect(() => {
    console.log('Count is now:', count.value);
});

count.value = 1;  // Logs: "Count is now: 1"
count.value = 2;  // Logs: "Count is now: 2"

Automatic Dependency Tracking

Effects automatically track which signals they read. No need to declare dependencies—Lightview figures it out:

const firstName = signal('Alice');
const lastName = signal('Smith');
const showFull = signal(true);

effect(() => {
    if (showFull.value) {
        // Tracks firstName, lastName, and showFull
        console.log(`${firstName.value} ${lastName.value}`);
    } else {
        // Only tracks firstName and showFull
        console.log(firstName.value);
    }
});

Stopping Effects

Effects return a stop function:

const count = signal(0);

const stop = effect(() => {
    console.log('Count:', count.value);
});

count.value = 1;  // Logs
count.value = 2;  // Logs

stop();  // Stop the effect

count.value = 3;  // Nothing logged

Common Patterns

Syncing to External Systems

const theme = signal('light');

effect(() => {
    document.body.setAttribute('data-theme', theme.value);
});

Local Storage Persistence

const settings = signal(
    JSON.parse(localStorage.getItem('settings')) || {}
);

effect(() => {
    localStorage.setItem('settings', JSON.stringify(settings.value));
});

API Calls

const userId = signal(1);
const userData = signal(null);

effect(async () => {
    const id = userId.value;
    const response = await fetch(`/api/users/${id}`);
    userData.value = await response.json();
});

Effects vs Computed

Use Case Use This
Derive a value from signals computed()
Side effects (logging, API calls, DOM) effect()
Value needed in UI computed()
Just need to "do something" effect()
const name = signal('World');
const log = signal([]);

effect(() => {
    log.value = [...log.value, `Hello, ${name.value}!`].slice(-5);
});

// Change name to see the effect in action