subscribe()
The subscribe() function calls a callback when source dependencies change. Unlike effect(), it separates the tracked source from the untracked callback.
Syntax
Section titled “Syntax”const unsubscribe = subscribe(source, callback)Parameters
Section titled “Parameters”source
: A function that reads signals. These reads are tracked as dependencies.
callback
: A function called with the source’s return value. Signal reads here are not tracked.
Return value
Section titled “Return value”An unsubscribe function that stops the subscription.
Description
Section titled “Description”The source function determines dependencies; the callback can read any signals without creating subscriptions:
const count = signal(0);const multiplier = signal(2);
subscribe( () => count(), // tracked (value) => console.log(value * multiplier()) // NOT tracked);
count(5); // logs: 10multiplier(3); // no log — multiplier isn't a dependencycount(6); // logs: 18Initial call
Section titled “Initial call”Like effects, subscribe() calls the callback immediately with the initial value:
const count = signal(0);
subscribe( () => count(), (value) => console.log('Count:', value));// logs: "Count: 0"
count(1);// logs: "Count: 1"Unsubscribing
Section titled “Unsubscribing”Call the returned function to stop the subscription:
const unsubscribe = subscribe( () => count(), (value) => console.log(value));
count(1); // logs: 1unsubscribe();count(2); // nothingExamples
Section titled “Examples”External system sync
Section titled “External system sync”Sync to an external system only when specific signals change:
const userId = signal('user-1');const settings = signal({ theme: 'dark' });
// Only re-sync when userId changes, not settingssubscribe( () => userId(), (id) => { externalSystem.setUser(id); externalSystem.applySettings(settings()); // read but not tracked });Debounced search with stable config
Section titled “Debounced search with stable config”const query = signal('');const config = signal({ limit: 10 });
subscribe( () => query(), (q) => { // config changes don't trigger new searches fetch(`/search?q=${q}&limit=${config().limit}`); });Computed source
Section titled “Computed source”The source can be any reactive expression:
const items = signal([1, 2, 3]);const filter = signal('all');
subscribe( () => { // Both items and filter are dependencies const all = items(); return filter() === 'all' ? all : all.filter(x => x > 2); }, (filtered) => { renderList(filtered); });See also
Section titled “See also”- effect() — Simpler API when you want all reads tracked
- computed() — For derived values, not side effects