effect
A side effect that runs automatically when reactive dependencies change.
API
function effect(effectFn: () => void): () => void
effectFn
: The function to run as a side effect. It will be re-executed whenever a signal read inside it changes.- Returns: A
cleanup
function that can be called to stop the effect and prevent further executions.
Basic Usage
An effect runs immediately, and then again whenever any of its dependencies change.
Call the returned cleanup
function to stop the effect when it’s no longer needed.
import { signal, effect } from '@hellajs/core';
const count = signal(0);
// This effect runs immediately, then whenever `count` changes.
const cleanup = effect(() => {
console.log(`The count is: ${count()}`);
});
count(1); // Logs: "The count is: 1"
count(2); // Logs: "The count is: 2"
// Stop the effect. Future changes to `count` will not be logged.
cleanup();
count(3); // (nothing is logged)
Key Concepts
Conditional Effects
An effect
only reacts to the signals that are actually read during the last execution.
import { signal, effect } from '@hellajs/core';
const showData = signal(true);
const data = signal('value');
effect(() => {
if (showData()) {
console.log(data()); // Only reacts to 'data' when showData is true
}
});
Cleanup Functions
The effect
function returns a cleanup function that disposes of the effect
and prevents memory leaks.
import { effect } from '@hellajs/core';
const cleanup = effect(() => {
// Side effect logic
});
// Call cleanup when no longer needed
cleanup();
Important Considerations
Async Functions
Do not pass an async
function directly to effect
. Effects should be synchronous functions that may contain asynchronous operations.
import { effect } from '@hellajs/core';
// ❌ Async function directly
effect(async () => { /* ... */ });
// ✅ Handle async operations inside
effect(() => {
fetch('/api/data').then(data => {
// Handle the data here
console.log(data);
});
});
Infinite Loops
Avoid writing to signals that the effect
reads from, as this creates infinite loops.
import { signal, effect, untracked } from '@hellajs/core';
const count = signal(0);
// ❌ Effect triggers itself
effect(() => {
count(count() + 1);
});
// ✅ Use untracked for non-reactive reads
effect(() => {
const current = untracked(() => count());
console.log(`Count: ${current}`);
});