Angular Signals vs React Hooks: A Practical Comparison
Benchmarks, DX comparison, and real-world patterns for both reactivity models. Which one wins?
Both models solve derived state and effects. They differ in what they track: signals track values, hooks track renders. Almost every practical difference follows from that one sentence.
The same feature, twice
// Angular — dependencies are discovered from reads, granularity is the signal
@Component({
selector: "app-cart",
template: `
<input [value]="query()" (input)="query.set($any($event.target).value)" />
<p>{{ visible().length }} of {{ items().length }} — {{ total() | currency }}</p>
`,
})
export class CartComponent {
items = signal<Item[]>([]);
query = signal("");
visible = computed(() =>
this.items().filter((i) => i.name.toLowerCase().includes(this.query().toLowerCase())),
);
total = computed(() => this.visible().reduce((s, i) => s + i.price * i.qty, 0));
}// React — dependencies are declared, granularity is the component
function Cart({ items }: { items: Item[] }) {
const [query, setQuery] = useState("");
const visible = useMemo(
() => items.filter((i) => i.name.toLowerCase().includes(query.toLowerCase())),
[items, query],
);
const total = useMemo(() => visible.reduce((s, i) => s + i.price * i.qty, 0), [visible]);
return (
<>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<p>{visible.length} of {items.length} — {format(total)}</p>
</>
);
}What the numbers said
On a 5,000-row grid with a single cell update, signals win clearly: Angular re-evaluated one computed and patched one DOM node, while React re-rendered the row subtree unless I memoised aggressively. On full-list replacement the two converged — that work is dominated by DOM, not by reactivity.
- –Signals: fine-grained updates for free, no dependency arrays, no stale-closure bugs.
- –Hooks: a smaller mental model at the component level, an enormous ecosystem, and predictable render semantics.
- –Both punish untracked mutation — the failure modes just look different.
Neither wins outright. If your app is dashboard-shaped with dense high-frequency updates, signals remove a category of manual memoisation. Otherwise pick the ecosystem you can hire for.