Menu

React или Vue: различия на примерах кода рядом

React и Vue это инструменты JavaScript для построения пользовательских интерфейсов из компонентов. Они различаются разметкой (JSX или шаблоны), тем, как реагируют на изменения (неизменяемое состояние и повторные рендеры или изменяемые реактивные ref), и тем, какая часть экосистемы официальная.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

React и Vue это инструменты JavaScript для построения пользовательских интерфейсов из компонентов (React называет себя библиотекой, Vue прогрессивным фреймворком), и у них общие основные идеи: пропсы вниз, события вверх, реактивное состояние, виртуальный DOM. На практике различия такие: React пишет разметку в JSX и ожидает, что состояние заменяют через сеттер, а Vue пишет разметку в шаблонах HTML внутри однофайловых компонентов и позволяет менять реактивные значения напрямую. Вот счётчик на React:

И тот же счётчик как однофайловый компонент Vue (Counter.vue):

<script setup>
import { ref } from 'vue';

const count = ref(0);
</script>

<template>
    <button @click="count++">Clicked {{ count }} times</button>
</template>

useState(0) становится ref(0), onClick становится @click, а {count} становится {{ count }}. Видимое различие это count++: Vue позволяет менять значение на месте, и его система реактивности это замечает. React нужен setCount, потому что он перерендеривает, только когда вы даёте ему новое значение.

JSX или однофайловые компоненты

Компонент React это функция JavaScript, которая возвращает JSX. Условия пишутся через && или тернарный оператор, списки через .map(), а стили берутся из того, что вы выберете (файлы CSS, CSS-модули, утилитарный фреймворк).

Компонент Vue обычно это файл .vue из трёх блоков: <script setup> для логики, <template> для разметки и необязательный <style scoped>, CSS которого применяется только к этому компоненту. Шаблоны используют директивы: v-if, v-for, v-model для двусторонней привязки поля, :prop для привязки значения и @event для прослушивания. Шаблоны оставляют разметку читаемой для любого, кто знает HTML; JSX даёт в разметке весь JavaScript. Vue тоже может использовать JSX, а React не может использовать шаблоны, но большая часть кода в каждом следует своему варианту по умолчанию.

Вот отфильтрованный список, вторая функция для сравнения.

Наберите xyz, чтобы увидеть сообщение о пустом списке, затем удалите. Версия на Vue:

<script setup>
import { ref, computed } from 'vue';

const fruits = ['Apple', 'Banana', 'Cherry', 'Grape', 'Mango', 'Peach'];
const query = ref('');

const visible = computed(() =>
    fruits.filter((f) => f.toLowerCase().includes(query.value.toLowerCase()))
);
</script>

<template>
    <input v-model="query" placeholder="Filter fruit" />
    <ul>
        <li v-for="fruit in visible" :key="fruit">{{ fruit }}</li>
        <li v-if="visible.length === 0">No match</li>
    </ul>
</template>

v-model заменяет пару value и onChange, а computed заменяет обычную переменную. В React visible пересчитывается при каждом рендере, потому что функция компонента выполняется заново; во Vue computed кэширует его и пересчитывает только при изменении query. Оба используют key, чтобы различать элементы списка.

Модель реактивности

Это самое глубокое различие между ними.

React: неизменяемое состояние и повторные рендеры. Состояние это снимок. Вы вызываете сеттер с новым значением, React снова выполняет функцию компонента, сравнивает новый JSX со старым и обновляет DOM. React сравнивает значения через Object.is, поэтому изменение объекта или массива на месте и передача того же обратно выглядит так, будто ничего не изменилось.

Нажмите «push() in place», и на экране ничего не изменится, потому что массив тот же объект. Затем нажмите «New array»: рендер покажет и pushed, потому что прежняя мутация действительно произошла, просто у React не было причины смотреть. Страница о useState подробно разбирает этот шаблон.

Vue: изменяемые реактивные значения. ref или объект reactive записывает, кто его читает (ref через геттер .value, объект reactive через прокси). Когда вы в него пишете, Vue точно знает, какие вычисляемые значения, наблюдатели и части шаблона от него зависят, и обновляет только их. Во Vue items.value.push('pushed') обновляет экран. Вы пишете меньше церемоний и отказываетесь от гарантии, что значение никогда не изменится у вас за спиной.

Ни одна модель не быстрее настолько, чтобы это имело значение для типичных приложений. React может выполнять больше кода компонентов на одно изменение и полагается на мемоизацию (вручную или через React Compiler), чтобы пропускать работу; Vue отслеживает зависимости во время выполнения и поэтому пропускает эту работу по умолчанию.

Composition API или хуки

Composition API во Vue 3 и хуки React решают одну задачу: собирать связанные состояние и логику вместе и переиспользовать их в разных компонентах. Vue называет переиспользуемые функции composables (useMouse()), React называет их пользовательскими хуками (useMouse()). Правила различаются из-за того, когда выполняется код.

  • Когда выполняется. setup во Vue выполняется один раз при создании компонента. Функция компонента React выполняется при каждом рендере, и хуки внутри неё выполняются вместе с ней.
  • Правила порядка. React сопоставляет хуки по порядку вызова, поэтому их нельзя вызывать внутри условий или циклов. Во Vue такого правила для ref и computed нет, потому что setup выполняется один раз.
  • Зависимости. Эффекты и мемо в React перечисляют зависимости в массиве, который вы поддерживаете. watchEffect и computed во Vue отслеживают то, что читают, автоматически.
  • Устаревшие значения. Колбэк React может захватить старое значение состояния из более раннего рендера (классическая ошибка с setInterval). Колбэк Vue читает count.value в момент вызова и всегда видит текущее значение.

Модель React делает каждый рендер чистой функцией от пропсов и состояния, что легко тестировать и обдумывать. Модель Vue убирает целый класс ошибок с массивами зависимостей. Разработчики, знающие одно, обычно быстро осваивают другое.

Экосистема

ReactVue
РазметкаJSXШаблоны HTML в файлах .vue (JSX по желанию)
Обновления состоянияЗаменить через сеттер, затем повторный рендерИзменить реактивное значение, зависимые обновятся
Переиспользование логикиПользовательские хукиComposables
Производные значенияВычисляются во время рендера, useMemocomputed (кэшируется)
Двусторонняя привязка поляvalue плюс onChangev-model
Изолированный CSSНе встроен (CSS-модули, библиотеки)<style scoped> встроен
МаршрутизацияReact Router, TanStack Router, фреймворкиVue Router (официальный)
Глобальное состояниеКонтекст, Zustand, Redux ToolkitPinia (официальная)
Фреймворк полного стекаNext.js, React Router в режиме фреймворкаNuxt
Мобильные приложенияReact NativeОфициального варианта нет (Capacitor, NativeScript-Vue)
Инструмент сборкиVite или фреймворкVite
Кто поддерживаетMeta и сообществоНезависимая основная команда и сообщество

Закономерность в этой таблице: основная команда Vue поддерживает роутер, хранилище и devtools вместе, поэтому у проекта на Vue для каждого есть очевидный вариант по умолчанию. React оставляет это сообществу, что даёт больше вариантов и больше решений. Vite, обычный инструмент сборки для новых проектов в обоих, начал создатель Vue.

Порог входа

Vue часто даёт более мягкий старт. Шаблоны читаются как уже знакомый вам HTML, v-model убирает шаблонный код контролируемых полей, а реактивное значение обновляет экран, когда вы его меняете. React сразу требует JSX и привычку к неизменяемым обновлениям, и страница о JSX это первое, что нужно большинству.

После основ разрыв сокращается. Vue добавляет свои понятия (ref или объекты reactive, .value в скриптах, но не в шаблонах, наблюдатели), а React добавляет эффекты, мемоизацию и правила хуков. Вакансии в вашем регионе это более полезный решающий довод, чем синтаксис.

Когда что выбрать

Выбирайте React, когда:

  • Вам нужен широкий выбор библиотек и компонентов сообщества или вы планируете делать нативные мобильные приложения на React Native.
  • Вам нравится держать логику и разметку в одной функции JavaScript и нужен фреймворк вроде Next.js.
  • Ваша команда ценит явные неизменяемые обновления, благодаря которым каждый рендер легко отследить.

Выбирайте Vue, когда:

  • Вам нужны официальные согласованные инструменты для маршрутизации и состояния и меньше решений.
  • В вашей команде есть дизайнеры или бэкенд-разработчики, которым удобны шаблоны HTML.
  • Вы добавляете интерактивность на существующие страницы с серверным рендерингом: Vue можно подключить на страницу тегом script и развивать дальше.

Оба зрелые и используются в продакшене компаниями любого размера, а понятия, изученные в одном (компоненты, пропсы, производное состояние, списки с ключами), напрямую переносятся в другой.

Часто задаваемые вопросы

Vue проще, чем React?

Многим новичкам Vue сначала кажется проще, потому что шаблоны похожи на обычный HTML, а изменение реактивного значения (count.value++) обновляет экран без сеттера. React требует изучить JSX и правило, что состояние нужно заменять, а не менять. После первых недель сложность примерно одинаковая.

Что лучше: React или Vue?

В целом ни один не выигрывает. React оставляет маршрутизацию и состояние библиотекам сообщества и имеет React Native для мобильных приложений. У Vue есть официальные роутер, хранилище и devtools, которые поддерживаются вместе, и шаблоны, которые многим проще читать. Выбирайте то, что использует ваша команда или рынок вакансий.

Чем Composition API во Vue отличается от хуков React?

Оба группируют логику с состоянием в переиспользуемые функции. setup во Vue выполняется один раз на компонент и отслеживает зависимости автоматически, поэтому нет массивов зависимостей и устаревших замыканий. Функция компонента React выполняется при каждом рендере, поэтому хуки должны вызываться каждый раз в одном порядке, а эффекты перечисляют свои зависимости.

Vue использует JSX?

Vue поддерживает JSX через плагин, но большая часть кода на Vue использует шаблоны HTML в однофайловых компонентах (файлах .vue). React почти везде использует JSX.

Какой аналог Next.js во Vue?

Nuxt. Как Next.js для React, он добавляет поверх Vue файловую маршрутизацию, серверный рендеринг, статическую генерацию и серверные маршруты.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ