Signals — the Core Primitive
createSignal, the getter/setter pair that powers every piece of reactive state in Solid.
2 min de lectura
Every reactive value in Solid ultimately traces back to a signal. If you understand createSignal deeply, the rest of Solid's reactivity model (memos, effects, stores) is just variations on the same idea.
Creating and reading a signal
import { createSignal } from "solid-js";
const [count, setCount] = createSignal(0);
console.log(count()); // 0
setCount(5);
console.log(count()); // 5createSignal(initialValue) returns a two-element array: a getter function and a setter function. This is deliberately different from React's useState, where the first element is the value itself. In Solid, count is never the number — it's always a function you call to read the current value. That's what makes it reactive: calling count() inside a tracking context (JSX, createEffect, createMemo) registers that context as a dependency, so it can be notified when the value changes.
Why a function, not a value
function Clock() {
const [time, setTime] = createSignal(new Date());
setInterval(() => setTime(new Date()), 1000);
return <p>Current time: {time().toLocaleTimeString()}</p>;
}Remember: Clock's function body runs exactly once. If time were a plain variable, <p> would show whatever the initial new Date() was, forever — there'd be no way to "re-render" since Solid doesn't re-render. Because time is a signal, {time().toLocaleTimeString()} is compiled into a live binding: Solid subscribes that specific text node to the signal, and every setTime(...) call updates the DOM directly, without re-running any component code.
Functional updates
The setter also accepts a function, which receives the previous value — the same pattern as React's functional setState, and for the same reason: it avoids stale-closure bugs when the update depends on the current value.
const [count, setCount] = createSignal(0);
function incrementTwice() {
setCount((prev) => prev + 1);
setCount((prev) => prev + 1);
}Signals hold any value
A signal isn't limited to primitives — it can hold an object, array, or anything else. The catch is that Solid's change detection for objects/arrays is reference-based, so mutating an object in place won't notify anything:
const [user, setUser] = createSignal({ name: "Ana", age: 30 });
// Won't trigger updates — same object reference
user().age = 31;
// Triggers updates — new object reference
setUser({ ...user(), age: 31 });For state that's naturally nested — a user profile, a list of settings — this pattern gets tedious fast, which is exactly why Solid provides createStore for structured state (covered later in this course). For simple, independent values, though, createSignal is the tool you'll reach for constantly, and it's worth being completely comfortable with the getter/setter shape before moving on.