Глава 10 Альтернативы React

React не значит реактивный

Книга
React. К вершинам мастерства

Fluent React: Build Fast, Performant, and Intuitive Web Applications

Глубокое погружение во внутреннее устройство React: JSX и продвинутые паттерны, виртуальный DOM и реконциляция, серверный рендеринг, конкурентный режим и серверные компоненты.

Глава 10 · Слово, которое все понимают по-разному

Что вообще значит «реактивный»

Термин «реактивный» описывает в программировании слишком многое. Чаще всего — системы, которые автоматически обновляются в ответ на изменения в данных: изменения распространяются по системе сами. Поэтому Vue.js и Svelte называют реактивными. React — при всём своём названии — традиционной модели реактивности не следует.

Традиционная реактивность

Зависимости между вычислениями отслеживаются автоматически по мере выполнения кода. Когда реактивная зависимость меняется, все вычисления, которые от неё зависят, выполняются повторно — сами.

Обычно это делается через привязку данных, отслеживание значений, сигналы и временные интервалы.

Сигнал — reactivity 101

Сигнал — реактивный примитив для создания реактивных значений. При чтении читатель, получающий сигнал, на него подписывается. При записи нового значения все подписчики получают уведомление.

По сути это знакомый шаблон pub/sub: подписчик подписывается на издателя, издатель рассылает уведомления.

React идёт другим путём. Вместо автоматического отслеживания зависимостей и распространения изменений он вводит более явный механизм обновления состояния — хук useState. При изменении состояния React не отображает обновление немедленно, а планирует повторный рендеринг, во время которого вся функция компонента запускается снова с новым состоянием.
Один и тот же счётчик · две модели

Крупнозернистая против мелкозернистой

Тот же счётчик в React и в Solid — платформе с реактивной моделью. Код почти совпадает, а происходящее внутри противоположно.

Counter.jsx · Reactкрупнозернистая
import React, { useState } from "react";

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

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}
Counter.jsx · Solidмелкозернистая
import { createSignal } from "solid";

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

  return (
    <div>
      <p>{count()}</p>
      <button onClick={() => setCount(count() + 1)}>+1</button>
    </div>
  );
}
React: вызывается setCount — и функция Counter вызывается повторно целиком, включая сам хук useState. Solid: вызывая count() внутри <p>, мы неявно подписали этот кусок JSX на реактивное значение; setCount уведомляет подписчиков, и функция Counter больше никогда не вызывается — обновляются только детализированные реактивные значения.
Формула, которую все цитируют

v = f(s) описывает как раз нереактивность

React часто отождествляют с выражением v = f(s) — представление является функцией своего состояния. Само это выражение и описывает нереактивный характер React: представление является функцией состояния, но не обновляется автоматически при его изменении. Оно обновляется, когда функция повторно выполняется с новым состоянием.

  • Состояние компонента или его пропсы изменяются — явно, через вызов сеттера.
  • React повторно отображает компонент, создавая новое поддерево виртуального DOM.
  • Сравнивает новое поддерево со старым и вычисляет минимальный набор фактических мутаций.
  • Применяет эти мутации к реальному DOM — здесь начинается согласование.
Если React очеловечить, он сказал бы: «Расскажите мне, какое состояние вы ожидаете, и я позабочусь об этом».
Пример из книги · зависимые значения

Производное значение: считается само или пересчитывается?

Компонент показывает список элементов и их количество. В реактивной системе количество обновляется автоматически при каждом изменении списка.

ItemList.svelteреактивная инструкция
<script>
  let items = ['Apple', 'Banana', 'Cherry'];
  $: count = items.length;
</script>

<p>{count} items:</p>
<ul>
  {#each items as item (item)}
    <li>{item}</li>
  {/each}
</ul>
ItemList.jsx · Reactзначение на этапе рендеринга
function ItemList() {
  const [items, setItems] = useState(["Apple", "Banana"]);
  const count = items.length;

  // ... где-то происходит обновление items ...

  return (
    <div>
      <p>{count} items:</p>
      <ul>{items.map((i) => <li key={i}>{i}</li>)}</ul>
    </div>
  );
}
Svelte: $: объявляет реактивную инструкцию — всякий раз, когда меняется items, count пересчитывается сам. React: count — не реактивное значение, а значение, полученное из текущего состояния на этапе рендеринга. Чтобы оно обновилось, нужно вызвать setItems и инициировать повторный рендеринг: count пересчитывается не потому, что «реагирует», а потому что функция ItemList активирована повторно.
Что React покупает этим обменом

Явность вместо автоматизма

Модель явного задания состояния и повторной визуализации — не недоработка, а выбор. Взамен автоматического распространения изменений она даёт три вещи.

Предсказуемость

Изменения не разбегаются по системе сами. Разработчик явно описывает, каким должен быть UI для данного состояния, и упрощает себе анализ состояния приложения в любой момент времени.

Атомарность и батчинг

Обновление состояния и результирующее обновление интерфейса связаны в рамках одной атомарной операции. Отсюда же — пакетное обновление состояния: несколько сеттеров дают один рендер.

Контроль

state и props как единственный источник отображения дают чёткую модель того, как изменения распространяются по приложению, а виртуальный DOM эффективно управляет обновлениями реального.

Плата за это ровно та, о которой говорит название доклада: компоненты React не реагируют автоматически на изменения в данных. React даёт команду применить необходимые обновления путём повторного выполнения функций, а не обновляет соответствующие значения на месте.
Вывод книги

В конечном счёте это спор о семантике

Книга не пытается закрыть вопрос лозунгом — она показывает, что ответ зависит от определения.

Реактивность = автоматическое распространение изменений

Тогда нет, React не является реактивным. Он не отслеживает зависимости сам и не рассылает изменения по системе — он перезапускает функции.

Реактивность = способность реагировать на изменения состояния предсказуемо и контролируемо

Тогда да, React безусловно можно считать реактивным — и именно эта трактовка объясняет, почему он оказался невероятно эффективным для сложных интерфейсов.

Главное, что стоит унести: универсального подхода к управлению состоянием и реактивностью не существует. У каждого инструмента свои сильные стороны и недостатки; понимание различий помогает выбрать подходящий и писать более эффективный код независимо от платформы.
Август 2026 · Сверяем часы

Изменился ли ответ за два года

Книга писалась до React 19 и до стабильного компилятора. Проверим, устояли ли её утверждения.

Утверждение книгиАвгуст 2026
в силе Реактивность React — крупнозернистая: перезапускается вся функция компонентаМодель не изменилась. React по-прежнему pull-based: сеттер планирует рендер, функция запускается заново, дальше согласование виртуального DOM
снято частично Мелкозернистость достижима, но «нужно помнить про memo»React Compiler v1.0 (стабилен с 7 октября 2025) расставляет мемоизацию сам, на основе анализа и эвристик. useMemo, useCallback и memo остались аварийным люком для точного контроля, а не повседневной обязанностью
в силе Сигналы — не путь ReactAngular 20, Vue 4, Solid сделали сигналы основным API. TC39 proposal-signalsStage 1, среди авторов Angular, Vue, Solid, Preact, Ember, Qwik, MobX; React выбрал компилятор
развилось Явный контроль над тем, что и когда рендеритсяReact 19.2 добавил <Activity> (видимый / скрытый / приостановленный UI), useEffectEvent, cacheSignal и частичный пререндеринг — больше контроля внутри той же нереактивной модели
Что забрать с собой

React не значит реактивный — в четырёх строках

  • Реактивность — это автоотслеживание зависимостей. Чтение подписывает, запись уведомляет. React так не работает: он требует явного вызова сеттера.
  • v = f(s) — про нереактивность. Представление есть функция состояния, но обновляется не само, а повторным выполнением функции с новым состоянием.
  • Крупнозернистая против мелкозернистой. React перезапускает функцию компонента целиком; сигнальные платформы обновляют только те узлы, которые читали значение.
  • Спор о семантике, а не о качестве. «Автораспространение изменений» — нет; «предсказуемая и контролируемая реакция на изменение состояния» — да. Модель React даёт превосходный баланс между контролем и удобством работы.

Что далее

Vue.js Пройдено
Антон Помазков
Angular Пройдено
Антон Помазков
Svelte Пройдено
Антон Помазков
Solid Пройдено
Антон Помазков
Qwik Пройдено
Антон Помазков
Общие шаблоны Пройдено
Артём Никифоров
Артём Никифоров
Артём Никифоров