On This Page
Reactive Controls
Reaction.create() provides the Reaction instance as the first argument, which can be used to control when and whether the reaction runs.
Reaction.create((reaction) => { console.log('Current value:', mySignal.get());});Stopping a Reaction
reaction.stop() permanently prevents a reaction from running again, even if its Signal dependencies change.
From the Return Value
Reaction.create() returns the reaction instance, so you can stop it externally.
const counter = new Signal(0);
const reaction = Reaction.create(() => { console.log('Count:', counter.get());});
counter.increment(); // reaction runsreaction.stop();counter.increment(); // no longer updatingFrom Inside the Callback
The reaction instance is also passed as the first argument, so it can stop itself based on a condition.
const percentComplete = new Signal(0);Reaction.create((reaction) => { const currentPercent = percentComplete.get(); if(currentPercent >= 100) { reaction.stop(); return; } console.log('Progress:', currentPercent);});
percentComplete.increment(80);percentComplete.increment(20); // at 100, reaction stopspercentComplete.increment(50); // no longer updatingSkipping First Run
Reactions run immediately when created to discover their dependencies. Use reaction.firstRun to skip side effects during this initial execution.
const score = new Signal(0);
Reaction.create((reaction) => { const currentScore = score.get(); if (!reaction.firstRun) { console.log(`Score: ${currentScore}`); }});Dependency Pitfall
Signal accesses must be reachable during the first run to register as dependencies. A common mistake is returning early on the first run, which prevents any dependencies from being established.
const score = new Signal(0);
// reaction wont rerun when score changes because dependency is not establishedReaction.create((reaction) => { if (reaction.firstRun) { return; } console.log(`Score: ${score.get()}`);});Suppressing Reactivity
Nonreactive
Reaction.nonreactive() reads reactive values inside a reaction without creating dependencies.
const name = new Signal('Alice');const status = new Signal('Online');
Reaction.create(() => { const currentName = name.get(); // dependency created const currentStatus = Reaction.nonreactive(() => status.get()); // no dependency console.log(`${currentName} is ${currentStatus}`);});
name.set('Bob'); // triggers reactionstatus.set('Offline'); // does not trigger reactionPeek
signal.peek() reads a single signal’s value without creating a dependency. Same effect as nonreactive but scoped to one value.
const counter = new Signal(0);const trigger = new Signal(false);
Reaction.create(() => { trigger.get(); // dependency created const currentCount = counter.peek(); // no dependency console.log('Count:', currentCount);});
counter.set(1); // does not trigger reactiontrigger.set(true); // triggers reactionSee Reactive Performance for
guardandsubscribe, which optimize reactivity for specific patterns.