|
| 1 | +--- |
| 2 | +title: "Reactivity Basics" |
| 3 | +order: 1 |
| 4 | +--- |
| 5 | + |
| 6 | + |
| 7 | +Reactivity is the foundation of Solid. |
| 8 | +It’s the programming model where **changes in data automatically update the parts of your app that depend on it**. |
| 9 | + |
| 10 | +Solid’s approach is **fine-grained**: instead of re-rendering entire components, only the exact parts of the DOM that depend on a value update. This makes applications efficient and responsive, even as they grow. |
| 11 | + |
| 12 | +## Core Principles of Reactivity |
| 13 | + |
| 14 | +Solid’s reactivity is built on three key ideas: **signals, subscribers, and tracking scopes**. |
| 15 | +Together, these create a system where updates are precise, automatic, and efficient. |
| 16 | + |
| 17 | +### Signals: Reactive Values |
| 18 | + |
| 19 | +A **signal** is a reactive value container. |
| 20 | +They consist of 2 parts: |
| 21 | +- **Getter** → reads the current value. |
| 22 | +- **Setter** → updates the value and notifies dependents. |
| 23 | + |
| 24 | +```tsx |
| 25 | +const [count, setCount] = createSignal(0); |
| 26 | + |
| 27 | +console.log(count()); // 0 |
| 28 | +setCount(1); |
| 29 | +console.log(count()); // 1 |
| 30 | +``` |
| 31 | + |
| 32 | +Signals can hold any type of value: |
| 33 | +- primitives (string, number, boolean) |
| 34 | +- objects and arrays |
| 35 | +- application state (user, theme, current page) |
| 36 | + |
| 37 | +Learn more in the [Signals page](/reactivity/signals). |
| 38 | + |
| 39 | +### Subscribers: Reactive Consumers |
| 40 | + |
| 41 | +If signals are the **source of truth**, subscribers are the **reactive consumers**. |
| 42 | + |
| 43 | +A subscriber is any function or construct that reads a signal inside a tracking scope and automatically re-runs whenever it changes. |
| 44 | +This is what makes Solid’s reactivity *fine-grained*: only the subscribers that depend on a signal update, not the entire component. |
| 45 | + |
| 46 | +How subscribers work: |
| 47 | +1. **Observation** → subscriber runs and reads signals. |
| 48 | +2. **Dependency tracking** → those signals register the subscriber. |
| 49 | +3. **Response** → when a signal changes, the subscriber re-runs. |
| 50 | + |
| 51 | +### Tracking Scopes: Connecting Signals & Subscribers |
| 52 | + |
| 53 | +A **tracking scope** is the environment where Solid records which signals are being used. |
| 54 | +When a signal is read within a tracking scope, it registers the current subscriber as a dependency. |
| 55 | +Once that signal changes, it will notify the subscriber to re-run and update accordingly. |
| 56 | + |
| 57 | +Tracking scopes within Solid include: |
| 58 | +- Component render functions (JSX return values) |
| 59 | +- Reactive computations (e.g., `createMemo`) |
| 60 | +- Effects (e.g., `createEffect`) |
| 61 | + |
| 62 | +Example of a tracking vs non-tracking scope: |
| 63 | + |
| 64 | +```tsx |
| 65 | +import { createSignal } from "solid-js"; |
| 66 | + |
| 67 | +function Counter() { |
| 68 | + const [count, setCount] = createSignal(0); |
| 69 | + |
| 70 | + console.log(count()) // ❌ Not tracked — runs once |
| 71 | + |
| 72 | + return ( |
| 73 | + <div> |
| 74 | + <p>Count: {count()}</p> {/* ✅ tracked automatically - re-runs on update */} |
| 75 | + <button onClick={() => setCount(count() + 1)}>Increment</button> |
| 76 | + </div> |
| 77 | + ); |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +Tracking scopes are what enable **precise DOM updates**: only parts of the UI that depend on signals re-run, not the entire component. |
| 82 | +You can learn more about [component lifecycles in the Intro to Components page](/components/intro). |
| 83 | + |
| 84 | + |
| 85 | +## Related pages |
| 86 | +- [Signals](/reactivity/signals) |
| 87 | +- [Reactive Side Effects](/reactivity/effects) |
| 88 | +- [Introduction to Components](/components/intro) |
0 commit comments