Skip to content

Commit 4169aa7

Browse files
committed
effects
1 parent b3dcd5d commit 4169aa7

File tree

7 files changed

+172
-19
lines changed

7 files changed

+172
-19
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"title": "Getting Started",
3-
"pages": ["quick-start.mdx", "understanding-jsx.mdx", "todo.mdx"]
3+
"pages": ["installation.mdx", "understanding-jsx.mdx", "todo.mdx"]
44
}

src/routes/getting-started/quick-start.mdx renamed to src/routes/getting-started/installation.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: Quick Start
2+
title: Installation
33
order: 1
44
---
55

src/routes/intro.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ Traditionally, when a change occurs, the entire page would need to reload to dis
2424
With Solid's fine-grained reactive system, updates are only applied to the parts of the page that need to be updated.
2525
This decreases work and can result in faster load times as well as a smoother user experience overall.
2626

27-
## The Mental Model
27+
## The mental model
2828

2929
[TODO: Simple explanation of the mental model behind Solid]
3030

31-
## Where to Go Next
31+
## Where to go next
3232

3333
- [Quick Start Guide](https://solidjs.com/docs/getting-started)
3434
- [Reactivity Overview](/concepts/reactivity/)

src/routes/reactivity/basics.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ It’s the programming model where **changes in data automatically update the pa
1010
Solid’s approach is **fine-grained**: only the exact parts of the DOM that depend on a value update.
1111
This makes applications efficient and responsive, even as they grow.
1212

13-
## Core Principles of Reactivity
13+
## Core principles of reactivity
1414

1515
Solid’s reactivity is built on three key ideas: **signals, subscribers, and tracking scopes**.
1616
Together, these create a system where updates are precise, automatic, and efficient.
1717

18-
### Signals: Reactive Values
18+
### Signals: Reactive values
1919

2020
A **signal** is a reactive value container.
2121
They consist of 2 parts:
@@ -38,7 +38,7 @@ Signals can hold any type of value:
3838

3939
Learn more in the [Signals page](/reactivity/signals).
4040

41-
### Subscribers: Reactive Consumers
41+
### Subscribers: Reactive consumers
4242

4343
If signals are the **source of truth**, subscribers are the **reactive consumers**.
4444

@@ -51,7 +51,7 @@ How subscribers work:
5151
2. **Dependency tracking** → those signals register the subscriber.
5252
3. **Response** → when a signal changes, the subscriber re-runs.
5353

54-
### Tracking Scopes: Connecting Signals & Subscribers
54+
### Tracking Scopes: Connecting signals & subscribers
5555

5656
A **tracking scope** is the environment where Solid records which signals are being used.
5757
When a signal is read within a tracking scope, it registers the current subscriber as a dependency.
@@ -88,5 +88,5 @@ You can learn more about [component lifecycles in the Intro to Components page](
8888

8989
## Related pages
9090
- [Signals](/reactivity/signals)
91-
- [Reactive Side Effects](/reactivity/effects)
91+
- [Effects](/reactivity/effects)
9292
- [Introduction to Components](/components/intro)

src/routes/reactivity/data.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"pages": [
44
"basics.mdx",
55
"signals.mdx",
6-
"memos.mdx",
6+
"derived-state.mdx",
77
"effects.mdx",
88
"stores.mdx",
99
"resources.mdx",

src/routes/reactivity/memos.mdx renamed to src/routes/reactivity/derived-state.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: "Memoized Computations"
2+
title: "Derived State"
33
order: 3
44
---
55

src/routes/reactivity/effects.mdx

Lines changed: 161 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,165 @@
11
---
2-
title: "Derived Reactive Values"
2+
title: "Effects"
33
order: 4
44
---
55

6-
[TODO:
7-
Concept page for Effects
8-
- What are Effects
9-
- How to use them
10-
- When to use Effects
11-
- Move relevant sections to ref and vice versa
12-
]
6+
Effects are reactive functions that run when the values they depend on change.
7+
They’re the main way to manage side effects that occur outside an application's scope, such as:
8+
- DOM manipulation
9+
- Data fetching
10+
- Subscriptions
11+
12+
## What are Effects?
13+
14+
An effect is a reactive function that **runs automatically whenever the values it depends on change**.
15+
16+
Unlike [signals](/basics/signals) (which store state) or [memos](/basics/derived-state) (which derive state), effects connect your reactive data to the outside world.
17+
They are used for running code that has side effects, meaning it interacts with or modifies something beyond Solid's reactive graph, such as:
18+
19+
- updating or interacting with the DOM
20+
- logging values
21+
- fetching or subscribing to external data
22+
- setting up or cleaning up resources
23+
24+
Effects run **once when created** to establish its subscriptions, then **again whenever its dependencies change**.
25+
26+
## Creating an Effect
27+
28+
You create an effect using the `createEffect` function.
29+
It takes a **callback function** as its first argument, which contains the code you want to run reactively.
30+
31+
```tsx
32+
import { createSignal, createEffect } from "solid-js";
33+
34+
function Counter() {
35+
const [count, setCount] = createSignal(0);
36+
37+
createEffect(() => {
38+
console.log(`Count is: ${count()}`);
39+
});
40+
41+
return (
42+
<button onClick={() => setCount(count() + 1)}>
43+
Increment
44+
</button>
45+
);
46+
}
47+
```
48+
49+
In this example, the effect logs the current value of `count` to the console.
50+
The effect runs once when created, logging `Count is: 0`, and will run again whenever `count` changes, in this case when the button is clicked.
51+
52+
## Lifecycle of an Effect
53+
54+
An effect goes through a predictable cycle every time it's created and re-runs:
55+
56+
### 1. **Initialization**
57+
58+
When you call `createEffect`, the effect is immediately scheduled to run **once**.
59+
This first run happens **after the current render phase** finishes, or after the component function returns its JSX.
60+
This ensures that the DOM is already created and refs are assigned, allowing you to safely interact with the DOM.
61+
62+
```tsx
63+
createEffect(() => console.log("Initial run"));
64+
console.log("Hello");
65+
66+
// Output:
67+
// Hello
68+
// Initial run
69+
```
70+
71+
### 2. **Dependency tracking**
72+
73+
During its first run, the effect records every reactive value it accesses (such as signals or memos).
74+
It becomes subscribed to those values, which are now its **dependencies**.
75+
From then on, the effect automatically re‑runs whenever any of its dependencies change.
76+
77+
```tsx
78+
const [count, setCount] = createSignal(0);
79+
80+
createEffect(() => {
81+
console.log(`Count: ${count()}`);
82+
});
83+
84+
// Count: 0 runs immediately
85+
// every setCount(...) re‑runs the effect
86+
```
87+
88+
### 3. **Reactive Updates**
89+
90+
Whenever *any* dependency changes, the effects is scheduled to run again.
91+
This happens **after the current synchronous code completes**, ensuring that all changes are batched together.
92+
This means that if the dependencies change multiple times in quick succession, the effect will only run *once* after all changes are made:
93+
94+
```tsx
95+
const [count, setCount] = createSignal(0);
96+
const [name, setName] = createSignal("Solid");
97+
98+
createEffect(() => {
99+
console.log(`Count: ${count()}, Name: ${name()}`);
100+
});
101+
102+
setCount(1);
103+
setName("SolidJS");
104+
```
105+
106+
In this example, the effect will only log `Count: 1, Name: SolidJS` once, after all changes have been made.
107+
108+
### Lifecycle functions
109+
110+
Effects are reactive and run whenever their dependencies change, but sometimes finer control is needed.
111+
Solid provides lifecycle functions to manage when code runs and how it gets cleaned up.
112+
113+
These functions are especially useful for:
114+
- Running a side effect **only once** when the component mounts
115+
- Cleaning up resources, event listeners, or other side effects when the component unmounts
116+
117+
#### `onMount`
118+
119+
The [`onMount`](TODO) function allows you to run code **once** when the component is first added to the DOM.
120+
Unlike effects, `onMount` does **not track dependencies**.
121+
It will execute the callback once, and never again.
122+
123+
```tsx
124+
import { onMount, createSignal, createEffect } from "solid-js";
125+
126+
function Component() {
127+
const [data, setData] = createSignal(null);
128+
129+
createEffect(() => {
130+
// Still runs reactively whenever `data` changes
131+
console.log("Data:", data());
132+
});
133+
134+
onMount(async () => {
135+
// Runs only once when the component is mounted
136+
const res = await fetch("/api/data");
137+
setData(await res.json());
138+
});
139+
140+
return <div>...</div>;
141+
}
142+
```
143+
144+
#### `onCleanup`
145+
146+
Use [`onCleanup`](TODO) to **dispose of resources** before a component unmounts, or before an effect re-runs.
147+
This will prevent memory leaks and ensure that any subscriptions or event listeners are properly removed.
148+
149+
```tsx
150+
import { createSignal, onCleanup } from "solid-js";
151+
152+
function App() {
153+
const [count, setCount] = createSignal(0);
154+
155+
const timer = setInterval(() => setCount(c => c + 1), 1000);
156+
157+
onCleanup(() => {
158+
// Runs when the component unmounts
159+
clearInterval(timer);
160+
});
161+
162+
return <div>Count: {count()}</div>;
163+
}
164+
```
165+

0 commit comments

Comments
 (0)