Why You Should Start Using Signals in React (or Why Not Yet?)

Raaj AryanRaaj Aryan
4 min read

1. Introduction

A few weeks ago, I was deep into optimizing a React dashboard for one of my freelance clients. The project looked clean on the surface — reusable components, proper state management with hooks, and even some memoization to avoid unnecessary re-renders.

But something felt off.

As I added new widgets to the dashboard — live stats, graphs, real-time notifications — the UI started lagging. Even minor state changes triggered re-renders in places I didn’t expect. Debugging became a game of tracing useEffect, checking dependency arrays, and managing stale closures. Every performance improvement felt like a patch on a larger architectural inefficiency.

The main pain point?

  • State was distributed across deeply nested components.

  • useState was everywhere.

  • useEffect chains were hard to track.

  • Memoization (React.memo, useCallback) felt like fighting React itself.

That’s when I came across an article that mentioned something called Signals. I had heard the term before in Solid.js, but never gave it serious thought. But this time, I decided to dig deeper.

And honestly, it changed how I think about reactivity in UI development.


2. What Are Signals?

Let’s start simple.

The Layman Explanation

Imagine you have a value — say, a counter. Now imagine any place that uses this counter automatically updates when the value changes, without you writing any special logic for re-rendering or managing dependencies.

That’s a Signal.

You don’t need useState, useEffect, or even memo. Signals just work — they’re reactive by nature. When a signal’s value changes, everything subscribed to it reacts automatically and precisely.

The Technical Definition

A Signal is a reactive primitive — a small unit of state — that notifies dependents when it changes. It doesn’t trigger component-level re-renders like React state does. Instead, it updates only the part of the DOM that depends on it.

This fine-grained reactivity is what makes Signals so powerful.

Code Comparison: React vs Signals

Let me show you a simple example — a counter.

React Version:

// Counter.jsx
import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

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

Now with Signals (using Preact Signals):

// Counter.jsx
import { signal } from "@preact/signals-react";

const count = signal(0);

export default function Counter() {
  return (
    <div>
      <p>Count: {count.value}</p>
      <button onClick={() => count.value++}>Increment</button>
    </div>
  );
}

What's Different:

  • No hooks.

  • No state per component — the signal exists outside and still works.

  • Only the exact DOM node (<p>) updates when the signal changes.

How It Feels Different

Using signals felt… surprisingly natural.

  • The code is cleaner — no boilerplate hooks.

  • It’s predictable — changes propagate where they’re used.

  • It avoids unnecessary re-renders — which, in large apps, becomes critical.

Of course, it’s not about replacing React. But it opens the door to thinking differently about state.


3. Signals vs React State: A Developer's Viewpoint

Now let’s talk experience — the good, the not-so-good, and the trade-offs.

What I Loved About Signals

  • No unnecessary re-renders. Since signals update only where they're used, the rest of the component tree stays untouched.

  • Freedom from hook rules. You’re not restricted by the "rules of hooks" (no conditionals, top-level only, etc.).

  • Composable logic. Signals can be derived, composed, or reused without useEffect.

For instance:

const price = signal(100);
const quantity = signal(2);
const total = computed(() => price.value * quantity.value);

No useMemo, no tracking dependencies. It just works.

What React Still Does Better

As much as I appreciated the elegance of Signals, I wouldn’t rush to replace React’s state system entirely.

  • Ecosystem support. React has years of tools, libraries, and community patterns.

  • DevTools integration. Debugging with React is well-supported. Signals still lack that full ecosystem visibility.

  • Predictability in teams. React’s state model — though verbose — is familiar to most developers. Signals introduce a different mindset.

What I Struggled With

  • Mindset shift. I had to unlearn the habit of thinking in components + hooks and start thinking in terms of reactive values and computations.

  • TypeScript support. Early versions didn’t always provide perfect autocompletion or type inference. This has improved over time, but it’s something to watch.

  • Team-wide adoption. If you're working in a team, especially one that's deep into React, introducing signals might create friction or confusion.


🔗 👉 Click here to read the full Blog on TheCampusCoders

10
Subscribe to my newsletter

Read articles from Raaj Aryan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Raaj Aryan
Raaj Aryan

MERN Stack Developer • Open Source Contributor • DSA With Java • Freelancer • Youtuber • Problem-solving •