React — это JavaScript-библиотека для построения пользовательских интерфейсов, созданная и поддерживаемая Facebook (Meta). В отличие от Vue или Angular, React — именно библиотека: она отвечает только за UI-слой, а маршрутизацию, управление состоянием и другие задачи вы решаете дополнительными пакетами по своему выбору.
Это ключевое отличие: React даёт больше свободы, но требует больше решений от разработчика.
До React (и jQuery-эпохи) обновление интерфейса выглядело так:
// Ручное управление DOM — императивный подход
let count = 0
const display = document.getElementById('count')
const button = document.getElementById('btn')
button.addEventListener('click', () => {
count++
display.textContent = count // вручную синхронизируем UI с данными
// При сложных UI это превращается в хаос:
// нужно помнить о КАЖДОМ элементе, который зависит от count
document.getElementById('badge').textContent = count
document.getElementById('title').textContent = `Счётчик: ${count}`
if (count > 10) {
document.getElementById('warning').style.display = 'block'
}
})React предлагает декларативный подход: вы описываете КАК выглядит UI для данного состояния, а React сам решает что изменить в DOM:
// React — декларативный подход
function Counter() {
const [count, setCount] = React.useState(0)
return (
<div>
<p>{count}</p>
<span className="badge">{count}</span>
<h1>Счётчик: {count}</h1>
{count > 10 && <p className="warning">Слишком много!</p>}
<button onClick={() => setCount(count + 1)}>+</button>
</div>
)
}Вы описываете "что отображать", а не "как обновлять". React сам эффективно обновит только изменившиеся части DOM.
React поддерживает виртуальный DOM (Virtual DOM) — облегчённое JavaScript-представление реального DOM. Алгоритм работы:
1. При изменении состояния React строит новое виртуальное дерево
2. Сравнивает его со старым виртуальным деревом (алгоритм diffing)
3. Вычисляет минимальный набор изменений (reconciliation)
4. Применяет только эти изменения к реальному DOM (batching)
Прямые операции с реальным DOM дорогостоящие — виртуальный DOM позволяет минимизировать их количество.
| Критерий | React | Vue 3 | Angular |
|---|---|---|---|
| Тип | Библиотека | Прогрессивный фреймворк | Полный фреймворк |
| Язык | JSX + JS/TS | SFC (.vue) + JS/TS | TypeScript (обязательно) |
| Экосистема | Свободный выбор | Частично включена | Всё включено |
| Порог входа | Средний | Низкий | Высокий |
| Размер | ~45kb | ~30kb | ~150kb+ |
| Использование | Meta, Netflix, Airbnb | Alibaba, Xiaomi | Google, enterprise |
Вы уже знаете Vue 3 — React будет понятен: те же концепции компонентов и реактивности, просто другой синтаксис и философия.
Современный способ создать React-проект — Vite (он же рекомендован для Vue):
# Создать новый React + TypeScript проект
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run devТакже популярен Next.js — React-фреймворк с SSR, файловым роутингом и многим другим (для продакшн-приложений):
npx create-next-app@latest my-app --typescriptReact-приложение — это дерево компонентов. Каждый компонент — это функция, которая принимает данные (props) и возвращает описание UI (JSX):
// App.jsx — корневой компонент
function App() {
return (
<div>
<Header /> // дочерний компонент
<main>
<ProductList /> // компонент-контейнер
</main>
<Footer />
</div>
)
}Компоненты — строительные блоки. Каждый инкапсулирует собственную логику, состояние и отображение.
Сравнение императивного (jQuery-стиль) и декларативного (React-стиль) подходов: счётчик двумя способами
// ============================================================
// ИМПЕРАТИВНЫЙ ПОДХОД (jQuery / vanilla JS)
// Вручную управляем каждым элементом DOM
// ============================================================
function createImperativeCounter(container) {
let count = 0
let domOperations = 0 // считаем обращения к DOM
// Создаём DOM-элементы вручную
const wrapper = document.createElement('div')
const display = document.createElement('h2')
const badge = document.createElement('span')
const btn = document.createElement('button')
display.textContent = `Счётчик: ${count}`
badge.textContent = count
btn.textContent = '+1'
wrapper.append(display, badge, btn)
domOperations += 3 // три операции создания
btn.addEventListener('click', () => {
count++
// Обновляем КАЖДЫЙ элемент вручную
display.textContent = `Счётчик: ${count}` // DOM операция 1
badge.textContent = count // DOM операция 2
domOperations += 2
console.log(`[Императивно] Клик #${count}, DOM операций всего: ${domOperations}`)
})
return wrapper
}
// ============================================================
// ДЕКЛАРАТИВНЫЙ ПОДХОД (имитация React)
// Описываем желаемое состояние — рантайм решает что обновить
// ============================================================
function createDeclarativeCounter() {
let count = 0
let domOperations = 0
// "Рендер-функция" описывает весь UI как HTML-строку
function render(state) {
return `
<div>
<h2>Счётчик: ${state.count}</h2>
<span>${state.count}</span>
<button id="dec-btn">+1</button>
</div>
`
}
// Простая реализация "diffing": заменяем только изменившееся
let prevHTML = ''
function update(container) {
const newHTML = render({ count })
if (newHTML !== prevHTML) {
container.innerHTML = newHTML // 1 DOM операция на любое изменение!
domOperations++
prevHTML = newHTML
// Переподключаем обработчик после перерисовки
container.querySelector('#dec-btn').addEventListener('click', handleClick)
}
}
function handleClick() {
count++
console.log(`[Декларативно] Клик #${count}, DOM операций всего: ${domOperations + 1}`)
update(document.getElementById('decl-root'))
}
return { render: update, initialHTML: render({ count: 0 }) }
}
// --- Вывод в консоль для демонстрации ---
console.log('Императивный подход: при каждом клике обновляем N элементов вручную')
console.log('Декларативный подход: описываем результат, рантайм минимизирует DOM-операции')
console.log('')
console.log('React делает именно это — только намного умнее:')
console.log('вместо innerHTML он точечно обновляет изменившиеся узлы через Virtual DOM')
// React эквивалент (для справки):
// function Counter() {
// const [count, setCount] = React.useState(0)
// return (
// <div>
// <h2>Счётчик: {count}</h2>
// <span>{count}</span>
// <button onClick={() => setCount(count + 1)}>+1</button>
// </div>
// )
// }React — это JavaScript-библиотека для построения пользовательских интерфейсов, созданная и поддерживаемая Facebook (Meta). В отличие от Vue или Angular, React — именно библиотека: она отвечает только за UI-слой, а маршрутизацию, управление состоянием и другие задачи вы решаете дополнительными пакетами по своему выбору.
Это ключевое отличие: React даёт больше свободы, но требует больше решений от разработчика.
До React (и jQuery-эпохи) обновление интерфейса выглядело так:
// Ручное управление DOM — императивный подход
let count = 0
const display = document.getElementById('count')
const button = document.getElementById('btn')
button.addEventListener('click', () => {
count++
display.textContent = count // вручную синхронизируем UI с данными
// При сложных UI это превращается в хаос:
// нужно помнить о КАЖДОМ элементе, который зависит от count
document.getElementById('badge').textContent = count
document.getElementById('title').textContent = `Счётчик: ${count}`
if (count > 10) {
document.getElementById('warning').style.display = 'block'
}
})React предлагает декларативный подход: вы описываете КАК выглядит UI для данного состояния, а React сам решает что изменить в DOM:
// React — декларативный подход
function Counter() {
const [count, setCount] = React.useState(0)
return (
<div>
<p>{count}</p>
<span className="badge">{count}</span>
<h1>Счётчик: {count}</h1>
{count > 10 && <p className="warning">Слишком много!</p>}
<button onClick={() => setCount(count + 1)}>+</button>
</div>
)
}Вы описываете "что отображать", а не "как обновлять". React сам эффективно обновит только изменившиеся части DOM.
React поддерживает виртуальный DOM (Virtual DOM) — облегчённое JavaScript-представление реального DOM. Алгоритм работы:
1. При изменении состояния React строит новое виртуальное дерево
2. Сравнивает его со старым виртуальным деревом (алгоритм diffing)
3. Вычисляет минимальный набор изменений (reconciliation)
4. Применяет только эти изменения к реальному DOM (batching)
Прямые операции с реальным DOM дорогостоящие — виртуальный DOM позволяет минимизировать их количество.
| Критерий | React | Vue 3 | Angular |
|---|---|---|---|
| Тип | Библиотека | Прогрессивный фреймворк | Полный фреймворк |
| Язык | JSX + JS/TS | SFC (.vue) + JS/TS | TypeScript (обязательно) |
| Экосистема | Свободный выбор | Частично включена | Всё включено |
| Порог входа | Средний | Низкий | Высокий |
| Размер | ~45kb | ~30kb | ~150kb+ |
| Использование | Meta, Netflix, Airbnb | Alibaba, Xiaomi | Google, enterprise |
Вы уже знаете Vue 3 — React будет понятен: те же концепции компонентов и реактивности, просто другой синтаксис и философия.
Современный способ создать React-проект — Vite (он же рекомендован для Vue):
# Создать новый React + TypeScript проект
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run devТакже популярен Next.js — React-фреймворк с SSR, файловым роутингом и многим другим (для продакшн-приложений):
npx create-next-app@latest my-app --typescriptReact-приложение — это дерево компонентов. Каждый компонент — это функция, которая принимает данные (props) и возвращает описание UI (JSX):
// App.jsx — корневой компонент
function App() {
return (
<div>
<Header /> // дочерний компонент
<main>
<ProductList /> // компонент-контейнер
</main>
<Footer />
</div>
)
}Компоненты — строительные блоки. Каждый инкапсулирует собственную логику, состояние и отображение.
Сравнение императивного (jQuery-стиль) и декларативного (React-стиль) подходов: счётчик двумя способами
// ============================================================
// ИМПЕРАТИВНЫЙ ПОДХОД (jQuery / vanilla JS)
// Вручную управляем каждым элементом DOM
// ============================================================
function createImperativeCounter(container) {
let count = 0
let domOperations = 0 // считаем обращения к DOM
// Создаём DOM-элементы вручную
const wrapper = document.createElement('div')
const display = document.createElement('h2')
const badge = document.createElement('span')
const btn = document.createElement('button')
display.textContent = `Счётчик: ${count}`
badge.textContent = count
btn.textContent = '+1'
wrapper.append(display, badge, btn)
domOperations += 3 // три операции создания
btn.addEventListener('click', () => {
count++
// Обновляем КАЖДЫЙ элемент вручную
display.textContent = `Счётчик: ${count}` // DOM операция 1
badge.textContent = count // DOM операция 2
domOperations += 2
console.log(`[Императивно] Клик #${count}, DOM операций всего: ${domOperations}`)
})
return wrapper
}
// ============================================================
// ДЕКЛАРАТИВНЫЙ ПОДХОД (имитация React)
// Описываем желаемое состояние — рантайм решает что обновить
// ============================================================
function createDeclarativeCounter() {
let count = 0
let domOperations = 0
// "Рендер-функция" описывает весь UI как HTML-строку
function render(state) {
return `
<div>
<h2>Счётчик: ${state.count}</h2>
<span>${state.count}</span>
<button id="dec-btn">+1</button>
</div>
`
}
// Простая реализация "diffing": заменяем только изменившееся
let prevHTML = ''
function update(container) {
const newHTML = render({ count })
if (newHTML !== prevHTML) {
container.innerHTML = newHTML // 1 DOM операция на любое изменение!
domOperations++
prevHTML = newHTML
// Переподключаем обработчик после перерисовки
container.querySelector('#dec-btn').addEventListener('click', handleClick)
}
}
function handleClick() {
count++
console.log(`[Декларативно] Клик #${count}, DOM операций всего: ${domOperations + 1}`)
update(document.getElementById('decl-root'))
}
return { render: update, initialHTML: render({ count: 0 }) }
}
// --- Вывод в консоль для демонстрации ---
console.log('Императивный подход: при каждом клике обновляем N элементов вручную')
console.log('Декларативный подход: описываем результат, рантайм минимизирует DOM-операции')
console.log('')
console.log('React делает именно это — только намного умнее:')
console.log('вместо innerHTML он точечно обновляет изменившиеся узлы через Virtual DOM')
// React эквивалент (для справки):
// function Counter() {
// const [count, setCount] = React.useState(0)
// return (
// <div>
// <h2>Счётчик: {count}</h2>
// <span>{count}</span>
// <button onClick={() => setCount(count + 1)}>+1</button>
// </div>
// )
// }Создай компонент App, который отображает приветственное сообщение и описание React. Компонент должен показывать: заголовок h1 с текстом "Привет, React!", абзац p с объяснением что React — это декларативная библиотека для UI, и стилизованный блок div с классом-подсказкой о виртуальном DOM.
Присвой переменной title строку "Привет, React!". В JSX вставляй переменные через фигурные скобки: {title}, {description}. Компонент App должен возвращать JSX-разметку с div-обёрткой.