Сначала опишите поведение словами. Затем посмотрите, как каждая идея переводится на конкретный фреймворк.
В этой лаборатории мы не учим «с нуля» программировать на Angular или React. Мы берём одну и ту же задачу — список задач (TaskFlow) — и решаем её двумя способами, чтобы вы почувствовали разницу.
Прежде чем сравнивать два инструмента, разберёмся с главными словами. Это основа всей лабораторной.
Суть одним предложением: фреймворк сам вызывает ваш код (он «главный»), а библиотеку вызываете вы (главный — вы).
| Похоже | Отличается |
|---|---|
| И то, и другое — чужой код, который вы подключаете к проекту, чтобы не писать всё с нуля. | Фреймворк (Angular) навязывает структуру: «делай так, иначе не заработает». Библиотека (React) не навязывает структуру: берёте только то, что нужно. |
| На обоих можно построить один и тот же внешне интерфейс (тот же список задач). | Фреймворк даёт «всё включено»: роутинг, формы, запросы к серверу уже внутри. Библиотека даёт только интерфейс; роутинг и запросы берутся из других пакетов. |
| Оба помогают разбить экран на компоненты (детали конструктора). | Фреймворк требует писать компонент как класс с декоратором. Библиотека позволяет писать компонент как обычную функцию. |
Прежде чем писать код, запишите шаги на человеческом языке:
Посмотрите, как один и тот же шаг из «рецепта» выше называется в каждом инструменте.
| Шаг | Angular | React |
|---|---|---|
| Получить данные | Сервис + HttpClient + Observable | fetch / Axios + useEffect |
| Передать данные | @Input() или signals | props |
| Событие (клик) | (click)="handler()" | onClick={handler} |
| Изменить состояние | signal() / BehaviorSubject | useState / useReducer |
| Отобразить список | @for (task of tasks()) { ... } | {tasks.map(t => ...)} |
| Обновить UI | Автоматически | Автоматически |
Одна и та же задача — список задач с отметкой «выполнено». Решаем её дважды.
Контекст. Это компонент списка задач в приложении TaskFlow. Он хранит массив задач в «сигнале» и по клику переключает флаг completed у нужной задачи.
import { Component, signal } from '@angular/core';
@Component({
// selector — имя, под которым компонент вставляется в HTML
selector: 'app-task-list',
template: `
@for (task of tasks(); track task.id) {
<li [class.completed]="task.completed">
{{ task.title }}
<button (click)="toggle(task.id)">
{{ task.completed ? 'Done' : 'Todo' }}
</button>
</li>
}
`
})
export class TaskListComponent {
// signal — реактивное значение: при изменении UI сам перерисовывается
tasks = signal([]);
toggle(id) {
// .update меняет значение сигнала; для каждой задачи берём копию
// и у найденной по id инвертируем флаг completed (да/нет)
this.tasks.update(list =>
list.map(t =>
t.id === id ? {...t, completed: !t.completed} : t
)
);
}
}
Пошаговый разбор:
TaskListComponent с шаблоном.@for перебирает задачи из сигнала tasks() (скобки — это «прочитать значение сигнала»).<li> с кнопкой; класс completed добавляется, если задача выполнена.toggle(id)..update заменяет массив: у задачи с нужным id флаг completed меняется на противоположный.Контекст. Тот же компонент списка задач для TaskFlow, но написан на React. Задачи хранятся в «состоянии» через useState, а загрузка данных — в useEffect.
import { useState, useEffect } from 'react';
export default function TaskList() {
// useState возвращает пару: [значение, функция_обновления]
const [tasks, setTasks] = useState([]);
// useEffect запускается один раз при показе компонента (пустой [])
useEffect(() => {
fetchTasks().then(data => setTasks(data));
}, []);
// toggle меняет состояние: инвертирует completed у задачи по id
const toggle = (id) => {
setTasks(list =>
list.map(t =>
t.id === id ? {...t, completed: !t.completed} : t
)
);
};
return (
<ul>
{tasks.map(t => (
<li key={t.id}>
{t.title}
<button onClick={() => toggle(t.id)}>
{t.completed ? 'Done' : 'Todo'}
</button>
</li>
))}
</ul>
);
}
Пошаговый разбор:
useState([]) создаём состояние tasks и функцию setTasks.useEffect с пустым массивом [] запускается один раз и загружает задачи.return пишем JSX — это HTML внутри JavaScript (обратите внимание: class здесь className).tasks.map(...) превращает каждую задачу в <li> с кнопкой.onClick вызывается toggle(t.id).setTasks создаёт новый массив с инвертированным флагом completed у нужной задачи.signal() vs useState, @for vs .map, (click) vs onClick. Поняв шаги один раз, вы легко перенесёте их на любой инструмент.
Теперь — «крупным планом», чем инструменты отличаются по духу.
| Критерий | Angular | React |
|---|---|---|
| Подход | Классы + декораторы + шаблоны | Функции + хуки + JSX |
| Состояние | Signals / RxJS | useState / useContext |
| Роутинг, формы, HTTP | Встроены в фреймворк | Внешние библиотеки |
| Когда выбирать | Enterprise, команды, нужна строгость | Стартапы, гибкость, быстрые итерации |
| Похоже | Отличается |
|---|---|
| Оба перерисовывают экран автоматически при изменении данных. | Angular «знает», КАК перерисовать, через свою систему (signals/RxJS). React перерисовывает, сравнивая новое состояние со старым. |
| В обоих компонент — это переиспользуемая деталь интерфейса. | Angular — компонент это класс + отдельный HTML-шаблон. React — компонент это функция, внутри которой сразу пишется JSX (HTML в JS). |
| Оба — JavaScript-экосистема, оба бесплатны и популярны. | Angular — «конструктор с инструкцией» (фреймворк). React — «набор отдельных инструментов» (библиотека), остальное докупаете сами. |
▶️ Сравните: Angular-стиль vs React-стиль (псевдокод, который рисует две карточки рядом):
Angular_React_Urok_01.html и, глядя на таблицу шага 2, опишите вслух, как бы вы реализовали список задач. Не код — просто словами по 6 шагам.
Лаборатория 5 из 5 (последняя). ← Лаборатория 4 | Вернуться к уроку 1
| Термин | Жизненная аналогия | Коротко |
|---|---|---|
| Фреймворк | Конструктор Lego с инструкцией | Задаёт структуру приложения и порядок сборки, вы заполняете детали (Angular). |
| Библиотека | Ящик с отдельными инструментами | Набор готовых «кирпичиков», вы сами решаете, что брать и в каком порядке (React). |
| Компонент | Деталь конструктора | Переиспользуемая запчасть интерфейса, из которых собирается экран. |
| Сигнал (signal) | Группа в мессенджере | Значение с «подписчиками»: при изменении все получают уведомление и обновляются. |
| Состояние (state) | Статус заказа в магазине | Текущее положение дел: «в обработке / готов / ошибка»; смена перерисовывает экран. |
| JSX / шаблон | Чертёж детали конструктора | Описание того, как компонент выглядит: HTML внутри JS (React) или отдельный шаблон (Angular). |
1. Фреймворк — это «набор отдельных инструментов», который вы берёте по мере надобности. Верно или неверно?
Ответ: Неверно. Фреймворк — это «конструктор с инструкцией»: он диктует порядок сборки, а вы заполняете детали. «Ящик с инструментами» — это библиотека (React).
2. Сигнал похож на «группу в мессенджере» и сам уведомляет экран об изменениях. Верно или неверно?
Ответ: Верно. Как в группе мессенджера — стоит значению измениться, все подписчики (включая экран) получают уведомление и обновляются автоматически.
3. Angular и React используют одинаковые механизмы, просто разные названия? Верно или неверно?
Ответ: Почти. Шаги (получить → отобразить → изменить → обновить) одни и те же, а «словарь» разный: signal() vs useState, @for vs .map, (click) vs onClick. Как плита и микроволновка готовят одно блюдо по разным рецептам.