Skip to content

Solid.js Signals — Reactive State Management

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Solid.js Signals. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Solid.js signals: create reactive state, read and update values, track dependencies, and understand fine-grained reactivity at the core of Solid.js.

In this lesson, you'll create signals with createSignal(), read and update values, and understand how Solid.js tracks reactive dependencies automatically.

What You'll Learn

How to create signals, read and update values, understand dependency tracking, and use signals in JSX templates.

Why It Matters

Signals are the atomic unit of reactivity in Solid.js. Understanding them is essential before moving to effects, memos, and complex state management.

Real-World Use

Doda Browser's tab manager uses signals for each tab's title, URL, loading state, and favicon—each updating independently without affecting other tabs.

flowchart LR
    A[createSignal] --> B[Getter: count()]
    A --> C[Setter: setCount()]
    B --> D[DOM Binding]
    C --> E[Update Value]
    E --> D
    style A fill:#2c4f7c,color:#fff

Creating a Signal

import { createSignal } from "solid-js";

function Counter() {
  const [count, setCount] = createSignal(0);

  return (
    <button onClick={() => setCount(c => c + 1)}>
      Count: {count()}
    </button>
  );
}

Output: Clicking the button increments the count. Only the text node inside the button updates—not the entire component.

Signal Getters and Setters

const [name, setName] = createSignal("Alice");

// Read
console.log(name()); // "Alice"

// Update with value
setName("Bob");

// Update with function
setName(prev => prev + " Jr.");

Multiple Signals

function UserProfile() {
  const [name, setName] = createSignal("Alice");
  const [age, setAge] = createSignal(30);
  const [online, setOnline] = createSignal(true);

  return (
    <div>
      <p>Name: {name()}</p>
      <p>Age: {age()}</p>
      <p>Status: {online() ? "Online" : "Offline"}</p>
      <button onClick={() => setOnline(!online())}>Toggle</button>
    </div>
  );
}

Each signal is independent. Changing name doesn't affect age or online.

Signal with Default Value

const [items, setItems] = createSignal([]);
const [config, setConfig] = createSignal({ theme: "light", lang: "en" });

// Read default
console.log(items().length); // 0
console.log(config().theme); // "light"

Common Mistakes

  1. Calling the signal without parentheses: count() reads the value. count returns the getter function itself.
  2. Destructuring the signal return: const { 0: count, 1: setCount } = createSignal(0) breaks the pattern. Use array destructuring.
  3. Creating signals inside conditionals: Signals should be created at the top level of a component or module, not inside if/for blocks.
  4. Mutating arrays and objects directly: items().push(newItem) doesn't trigger updates. Always use the setter: setItems([...items(), newItem]).
  5. Reading signals outside reactive context: Signals read outside effects or JSX won't trigger re-execution when the signal changes.

Practice Questions

  1. How do you create a signal? Answer: const [getter, setter] = createSignal(initialValue).

  2. How do you read the current value of a signal? Answer: Call the getter as a function: count(). Without parentheses, you get the getter function itself.

  3. How do you update a signal based on its previous value? Answer: Pass a function to the setter: setCount(prev => prev + 1).

  4. What happens when a signal changes? Answer: Only the DOM nodes or effects that depend on that signal re-execute. No component re-render.

Challenge

Build a form with three signals: name, email, and message. Display a live preview of the submitted data below the form that updates as the user types.

Mini Project

Create a color picker with three signals: red, green, and blue (0-255). Display the current color as a live preview box and show the hex value. Use range sliders for input.

FAQ

Can I have a signal without an initial value?

: Yes. createSignal() without arguments returns undefined as the initial value.

Are signals synchronous?

: Yes. setCount(5) immediately updates the value. Effects scheduled to run on the next microtask see the new value.

Can I create signals outside components?

: Yes. Signals can be created at module level for shared state across components.

How many signals can I create?

: No practical limit. Each signal is lightweight. Create as many as needed.

What's Next

Learn about Solid.js Effects for running side effects in response to signal changes.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro