Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 

Repository files navigation

⚛️ React - Вопросы для собеседования и ответы

Содержание 📑

  1. Основы React.js
  2. Компоненты React
  3. Состояние и пропсы
  4. Виртуальный DOM и согласование
  5. Жизненный цикл компонента
  6. Хуки React
  7. React 19 и новее — новые возможности
  8. Серверные компоненты и серверные действия
  9. Конкурентный React
  10. Redux и современные инструменты управления состоянием
  11. React Router v7
  12. Context API
  13. Обработка ошибок
  14. Стилизация компонентов в React
  15. Порталы
  16. Тестирование в React
  17. Оптимизация производительности
  18. Серверный рендеринг и потоковая передача
  19. Инструменты сборки и развёртывание
  20. TypeScript и React
  21. Доступность в React
  22. Паттерны проектирования и структура файлов
  23. Классические паттерны GoF во Frontend (React и Vue)
  24. Безопасность в React и Next.js
  25. WebSocket в React и Next.js
  26. Мониторинг через Sentry
  27. React Native — введение
  28. Progressive Web Apps (PWA)
  29. Тестирование и LLM
  30. Дополнительные ресурсы

Основы React.js

В1. Что такое React.js и каковы его ключевые особенности в 2026 году?

React — это декларативная компонентная JavaScript-библиотека для создания пользовательских интерфейсов, поддерживаемая компанией Meta. Последняя стабильная версия — React 19.2 (октябрь 2025). Ключевые особенности в 2026 году:

  • Компонентная модель — интерфейс строится из композируемых, переиспользуемых компонентов.
  • Виртуальный DOM — эффективное согласование через виртуальное представление DOM-дерева.
  • Хуки — логика с состоянием в функциональных компонентах без использования классов.
  • Конкурентный рендеринг — React 18+ может прерывать, приостанавливать и возобновлять рендеринг для повышения отзывчивости.
  • Серверные компоненты React (RSC) — компоненты, которые рендерятся на сервере без клиентского JavaScript.
  • Действия React 19 (Actions) — асинхронная обработка форм и серверные мутации как первоклассные примитивы.
  • Suspense и потоковая передача — прогрессивная загрузка с границами <Suspense> и потоковая передача по HTTP. (Подробнее: React Suspense)
  • <Activity /> (React 19.2) — управление скрытым/видимым состоянием UI с сохранением состояния компонентов.
  • React Compiler — стабильный релиз (2025) с автоматическим мемоизированием.

В2. Чем React отличается от других фреймворков, таких как Vue и Angular?

  • React — это библиотека (не полноценный фреймворк); он отвечает только за уровень представления, а маршрутизация, управление состоянием и загрузка данных обеспечиваются экосистемой.
  • Vue имеет более мягкий порог входа благодаря однофайловым компонентам и встроенной реактивности.
  • Angular — это полноценный фреймворк с TypeScript-first подходом, внедрением зависимостей и CLI-ориентированным рабочим процессом.
  • JSX и JavaScript-центричный подход React дают больше гибкости, но требуют принятия большего количества архитектурных решений.

В3. Что такое JSX и как он работает?

JSX — это расширение синтаксиса JavaScript, которое выглядит как HTML, но компилируется в вызовы React.createElement() (или в более новую трансформацию JSX, не требующую импорта React):

// JSX
const element = <h1 className="title">Hello</h1>;

// Компилируется в (новая трансформация JSX)
import { jsx as _jsx } from 'react/jsx-runtime';
const element = _jsx("h1", { className: "title", children: "Hello" });

JSX позволяет смешивать JavaScript-выражения {}, условный рендеринг и рендеринг списков прямо в разметке. Он не обязателен, но повсеместно используется в экосистеме React.

В4. Что такое «пробрасывание пропсов» (prop drilling) и как его можно уменьшить?

Пробрасывание пропсов возникает, когда пропсы приходится передавать через множество промежуточных компонентов, которым они не нужны, лишь бы добраться до глубоко вложенного дочернего компонента. Способы решения:

  • Context API — передача значений по дереву без явного пробрасывания.
  • Zustand / Jotai / Redux — внешние хранилища состояния, доступные из любого компонента. (Подробнее: Zustand)
  • Серверные компоненты React — данные могут загружаться на уровне сервера и передаваться напрямую.
  • Композиция компонентов — реструктуризация компонентов для совместного размещения данных и их потребителей.

В5. Что такое расширение React Developer Tools и что оно позволяет делать?

React DevTools — это расширение для браузера Chrome и Firefox, которое позволяет:

  • Инспектировать дерево компонентов и пропсы/состояние каждого компонента.
  • Профилировать рендеры для выявления узких мест производительности.
  • Подсвечивать повторные рендеры компонентов в реальном времени.
  • Инспектировать серверные компоненты React и границы Suspense.
  • Отлаживать хуки с именованными состояниями и эффектами.
  • (React 19.2) Просматривать React Performance Tracks на панели Performance в Chrome DevTools для анализа таймингов планировщика и компонентов.

Компоненты React

В6. В чём разница между функциональными и классовыми компонентами?

Функциональные компоненты — это обычные JavaScript-функции, возвращающие JSX. Для работы с состоянием и жизненным циклом они используют хуки. Классовые компоненты наследуются от React.Component и используют методы жизненного цикла, такие как componentDidMount. В 2026 году классовые компоненты считаются устаревшими — весь новый код должен использовать функциональные компоненты с хуками.

// Современный функциональный компонент
function Greeting({ name }) {
  const [count, setCount] = useState(0);
  return <h1>Hello, {name}! Clicked {count} times.</h1>;
}

В7. Как создать переиспользуемый компонент?

Проектируйте компоненты так, чтобы они принимали пропсы для изменяемых данных, были сфокусированы на одной задаче и не содержали жёстко закодированных значений:

function Button({ label, variant = "primary", onClick, disabled = false }) {
  return (
    <button
      className={`btn btn--${variant}`}
      onClick={onClick}
      disabled={disabled}
    >
      {label}
    </button>
  );
}

В8. Как выполнить условный рендеринг компонента?

// Тернарный оператор
{isLoggedIn ? <Dashboard /> : <Login />}

// Короткое замыкание (рендеринг или ничего)
{isAdmin && <AdminPanel />}

// Nullish — рендеринг ничего
{error ? <ErrorMessage error={error} /> : null}

В9. Что такое компоненты высшего порядка (HOC) и используются ли они до сих пор?

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

function withAuth(Component) {
  return function AuthenticatedComponent(props) {
    const { user } = useAuth();
    if (!user) return <Redirect to="/login" />;
    return <Component {...props} user={user} />;
  };
}

Состояние и пропсы

В10. В чём разница между состоянием (state) и пропсами (props)?

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

В11. В чём разница между управляемыми и неуправляемыми компонентами?

  • Управляемые (controlled) — значение поля формы управляется состоянием React. Компонент является единственным источником истины.
  • Неуправляемые (uncontrolled) — DOM управляет значением поля самостоятельно; React получает доступ к нему через ref.
// Управляемый
const [value, setValue] = useState("");
<input value={value} onChange={(e) => setValue(e.target.value)} />

// Неуправляемый
const inputRef = useRef();
<input ref={inputRef} defaultValue="initial" />
// Доступ: inputRef.current.value

В React 19 новый паттерн действий <form> (Actions) снижает потребность в управляемых полях ввода во многих сценариях работы с формами.

В12. Что такое граница ошибок (error boundary)?

Граница ошибок — это классовый компонент, который перехватывает JavaScript-ошибки в дереве дочерних компонентов, логирует их и отображает резервный UI вместо падения приложения. Они перехватывают только ошибки во время рендеринга, методов жизненного цикла и конструкторов — но не в обработчиках событий или асинхронном коде.

class ErrorBoundary extends React.Component {
  state = { hasError: false };
  static getDerivedStateFromError() { return { hasError: true }; }
  componentDidCatch(error, info) { logErrorToService(error, info); }
  render() {
    return this.state.hasError
      ? <h2>Something went wrong.</h2>
      : this.props.children;
  }
}

В React 19 хук use и <ErrorBoundary> из библиотеки react-error-boundary (сторонняя) значительно упрощают этот паттерн.


Виртуальный DOM и согласование

В13. Что такое виртуальный DOM?

Виртуальный DOM — это представление реального DOM-дерева в оперативной памяти. При изменении состояния React создаёт новое виртуальное дерево, сравнивает его с предыдущим (согласование) и применяет к реальному DOM только минимальный набор изменений — что позволяет избежать дорогостоящих полных перерисовок DOM.

В14. Как работает алгоритм согласования React?

Согласователь React (Fiber, начиная с React 16) обрабатывает обновления как дерево узлов fiber. (Подробнее: React Fiber) Ключевые эвристики:

  1. Элементы разных типов создают совершенно разные деревья.
  2. Элементы одного типа обновляются на месте, переиспользуя DOM-узлы.
  3. Ключи (keys) помогают React определить, какие элементы в списке изменились, были добавлены или удалены.

Конкурентный рендерер React 18+ может прерывать согласование для обработки более приоритетных обновлений (например, пользовательский ввод), делая UI более отзывчивым.

В15. Что такое ключи в списках React и почему они важны?

Ключи — это стабильные, уникальные идентификаторы элементов списка. Они помогают React сопоставлять элементы между рендерами, чтобы избежать ненужного размонтирования/повторного монтирования. Используйте стабильные ID из ваших данных — никогда не используйте индексы массива в качестве ключей, если порядок списка может меняться, так как это приводит к некорректной привязке состояния и трудноуловимым ошибкам.

// ✅ Правильно
items.map(item => <Card key={item.id} data={item} />)

// ❌ Избегать для динамических списков
items.map((item, index) => <Card key={index} data={item} />)

В16. Что такое фрагменты React?

Фрагменты позволяют возвращать несколько элементов без добавления лишнего DOM-узла:

return (
  <>
    <dt>Term</dt>
    <dd>Definition</dd>
  </>
);

Используйте явную форму <React.Fragment key={id}>, когда вам нужен проп key в списке.


Жизненный цикл компонента

В17. Каковы основные фазы жизненного цикла в React?

В функциональных компонентах через хуки:

  • МонтированиеuseEffect(() => { /* инициализация */ }, []) выполняется после первого рендера.
  • ОбновлениеuseEffect(() => { /* побочный эффект */ }, [dep]) выполняется при изменении dep.
  • Размонтирование — функция очистки, возвращённая из useEffect, выполняется при размонтировании.

В18. Чем useLayoutEffect отличается от useEffect?

useLayoutEffect срабатывает синхронно после мутаций DOM, но до отрисовки браузером. Используйте его, когда нужно считать метрики макета (например, размеры элемента) и синхронно выполнить повторный рендер, чтобы предотвратить визуальное мерцание. useEffect срабатывает асинхронно после отрисовки и предпочтителен для большинства побочных эффектов (загрузка данных, подписки).

В19. Что такое getDerivedStateFromProps и когда его уместно использовать?

Это статический метод жизненного цикла классового компонента, который возвращает новое состояние, вычисленное на основе входящих пропсов перед каждым рендером. В функциональных компонентах вы вычисляете состояние прямо во время рендера или с помощью useMemo. Чрезмерное использование производного состояния — частый источник ошибок; предпочитайте поднятие состояния или использование селекторов.


Хуки React

В20. Что такое useState и как правильно обновлять состояние-объект?

const [user, setUser] = useState({ name: "", email: "" });

// ✅ Используем spread, чтобы не перезаписать другие поля
setUser(prev => ({ ...prev, name: "Alice" }));

В21. Что такое useEffect и как обрабатывать очистку?

useEffect(() => {
  const subscription = api.subscribe(id, handleUpdate);
  return () => subscription.unsubscribe(); // очистка при размонтировании или перед следующим запуском
}, [id]);

В22. Что такое useReducer и когда его стоит предпочесть перед useState?

useReducer управляет сложным состоянием с несколькими подзначениями или когда следующее состояние нетривиальным образом зависит от предыдущего:

function reducer(state, action) {
  switch (action.type) {
    case "increment": return { count: state.count + 1 };
    case "reset": return { count: 0 };
    default: return state;
  }
}

const [state, dispatch] = useReducer(reducer, { count: 0 });

Предпочитайте useReducer, когда переходы состояния имеют понятную семантику (именованные действия) или когда логику состояния нужно тестировать независимо.

В23. Что такое useMemo и useCallback и когда их нужно использовать?

  • useMemo — мемоизирует результат дорогостоящего вычисления. Перезапускается только при изменении зависимостей.
  • useCallback — мемоизирует ссылку на функцию. Предотвращает повторный рендер дочерних компонентов при изменении идентичности функции.
const expensiveValue = useMemo(() => computeHeavy(data), [data]);
const handleClick = useCallback(() => doSomething(id), [id]);

⚠️ С React Compiler, ставшим стабильным в 2025 году, ручной useMemo/useCallback в значительной степени не нужны в новых проектах. Компилятор автоматически мемоизирует компоненты и значения на этапе сборки.

В24. Что такое пользовательские хуки?

Пользовательские хуки — это функции с префиксом use, которые инкапсулируют и переиспользуют логику с состоянием между компонентами:

function useWindowSize() {
  const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
  useEffect(() => {
    const handler = () => setSize({ width: window.innerWidth, height: window.innerHeight });
    window.addEventListener("resize", handler);
    return () => window.removeEventListener("resize", handler);
  }, []);
  return size;
}

В25. Что такое хук useRef?

useRef возвращает изменяемый ref-объект, свойство .current которого сохраняется между рендерами, не вызывая повторных рендеров. Используется для:

  • Прямого доступа к DOM-узлам.
  • Хранения изменяемых значений, которые не должны вызывать повторный рендер (например, таймеры, предыдущие значения).
const inputRef = useRef(null);
<input ref={inputRef} />
// Фокус: inputRef.current.focus()

В React 19 ref-ссылки можно передавать как обычные пропсы — ref={myRef} — без необходимости использовать forwardRef.

В26. Что такое хук useTransition?

useTransition помечает обновление состояния как не срочное («переход»), позволяя React поддерживать UI отзывчивым, пока обновление обрабатывается:

const [isPending, startTransition] = useTransition();

startTransition(() => {
  setSearchQuery(input); // Не блокирует взаимодействие с пользователем
});

{isPending && <Spinner />}

В27. Что такое хук useDeferredValue?

Аналогично useTransition, useDeferredValue откладывает обновление значения до тех пор, пока не отрендерятся срочные обновления (например, ввод пользователя), предотвращая блокировку UI:

const deferredQuery = useDeferredValue(query);
// deferredQuery отстаёт от query; используйте его для дорогостоящих отфильтрованных списков

React 19 и новее — новые возможности

В28. Каковы основные новые возможности React 19 (19.0)?

React 19.0 (декабрь 2024) представил:

  • Действия (Actions) — асинхронные функции для обработки отправки форм и мутаций; интегрированы с <form action={...}>.
  • useActionState — управляет состоянием, состоянием ожидания и состоянием ошибки действия.
  • useOptimistic — применяет оптимистичные обновления UI до подтверждения сервером, откатывая при неудаче.
  • Хук use() — читает значение Promise или Context прямо в рендере, естественно интегрируясь с Suspense. Может вызываться условно, в отличие от других хуков.
  • React Compiler (стабильный в 2025) — автоматическое мемоизирование; устраняет необходимость в ручном useMemo/useCallback в большинстве случаев.
  • Ref как проп — ref теперь можно передавать как обычный проп (ref={ref}) без forwardRef.
  • <ThemeContext value="dark"> — сокращённая форма провайдера; обёртка .Provider больше не нужна.
  • Улучшенные сообщения об ошибках гидратации — гораздо более читаемые diff'ы при несовпадениях SSR.
  • Поддержка метаданных документа — теги <title>, <meta> и <link>, отрендеренные в компонентах, автоматически переносятся в <head>.

В29. Как работают действия React 19 и useActionState?

import { useActionState } from "react";

async function updateProfile(prevState, formData) {
  const result = await api.updateUser({ name: formData.get("name") });
  if (!result.ok) return { error: result.message };
  return { success: true };
}

function ProfileForm() {
  const [state, action, isPending] = useActionState(updateProfile, null);

  return (
    <form action={action}>
      <input name="name" />
      <button type="submit" disabled={isPending}>
        {isPending ? "Saving…" : "Save"}
      </button>
      {state?.error && <p>{state.error}</p>}
    </form>
  );
}

В30. Что такое useOptimistic?

useOptimistic позволяет немедленно показать оптимистичное (предполагаемо успешное) состояние UI, а затем автоматически синхронизировать его с реальным ответом сервера:

const [optimisticLikes, addOptimisticLike] = useOptimistic(
  likes,
  (currentLikes, newLike) => [...currentLikes, newLike]
);

async function handleLike() {
  addOptimisticLike(tempLike);   // Показать немедленно
  await api.postLike(postId);    // Реальный запрос в фоне
}

В31. Как работает хук use()?

use() разворачивает Promise или читает Context внутри функции рендера — его можно вызывать условно (в отличие от других хуков):

function UserProfile({ userPromise }) {
  const user = use(userPromise); // Приостанавливается до разрешения
  return <h1>{user.name}</h1>;
}

// Также заменяет useContext
const theme = use(ThemeContext);

В32. Что было добавлено в React 19.1 (март 2025)?

React 19.1 был релизом, сфокусированным на стабильности — без ломающих изменений и устареваний. Ключевые additions:

  • Owner Stack (captureOwnerStack) — новый API только для режима разработки, возвращающий цепочку компонентов, непосредственно ответственных за рендеринг данного компонента. Это отличается от стеков компонентов (которые показывают полную иерархию до ошибки); Owner Stack показывает, кто создал компонент, что значительно упрощает отладку сложных деревьев.
  • Улучшенный Suspense — улучшенная поддержка границ Suspense на фазах клиента, сервера и гидратации. (Подробнее: React Suspense)
  • unstable_prerender — экспериментальный API для предварительного рендеринга серверных компонентов React на сервере.
  • Поддержка потоковой передачи на Edge — исправления и улучшения для потоковой передачи в edge-окружениях.
// Owner Stack в пользовательском оверлее ошибок
function onError(error) {
  const ownerStack = captureOwnerStack(); // только для dev-режима
  logToService(error, { ownerStack });
}

В33. Что было добавлено в React 19.2 (октябрь 2025)?

React 19.2 сфокусирован на управлении производительностью, асинхронной оркестрации и улучшениях SSR:

Компонент <Activity />: Позволяет скрывать части UI с сохранением их состояния и отложенными обновлениями, в отличие от условного рендеринга (&&), который полностью размонтирует дерево.

import { Activity } from "react";

// До (уничтожает состояние при скрытии)
{isVisible && <Panel />}

// После (сохраняет состояние в скрытом виде)
<Activity mode={isVisible ? "visible" : "hidden"}>
  <Panel />
</Activity>

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

Хук useEffectEvent: Отделяет «событийную» логику от реактивной логики эффектов, решая распространённую проблему массива зависимостей, когда значение читается внутри эффекта, но не должно его запускать:

import { useEffectEvent } from "react";

function ChatRoom({ roomId, theme }) {
  const onConnected = useEffectEvent(() => {
    showNotification("Connected!", theme); // всегда читает актуальный theme
  });

  useEffect(() => {
    const conn = createConnection(serverUrl, roomId);
    conn.on("connected", () => onConnected());
    conn.connect();
    return () => conn.disconnect();
  }, [roomId]); // ✅ theme НЕ является зависимостью
}

Effect Events не должны добавляться в массив зависимостей и должны быть объявлены в том же компоненте или хуке, что и их эффект (контролируется линтером).

cacheSignal (только серверные компоненты): Возвращает AbortSignal, привязанный к времени жизни cache() React. Автоматически прерывает выполняющиеся fetch-запросы при истечении срока кэша или сбое рендеринга:

import { cache, cacheSignal } from "react";
const dedupedFetch = cache(fetch);

async function Component() {
  await dedupedFetch(url, { signal: cacheSignal() });
}

React Performance Tracks: Новые пользовательские треки на панели Performance в Chrome DevTools с двумя дорожками:

  • Треки планировщика (Scheduler) — показывает работу по приоритетам (блокирующая vs. переход), когда обновления были запланированы и отрендерены, и когда React уступил управление.
  • Треки компонентов (Components) — показывает отрендеренное дерево компонентов, тайминги монтирования/размонтирования и заблокированные рендеры.

Частичный предварительный рендеринг (Partial Pre-rendering): Позволяет предварительно отрендерить статическую оболочку страницы на CDN и возобновить рендеринг динамического содержимого позже:

// Предварительный рендеринг статической оболочки
const { prelude, postponed } = await prerender(<App />, { signal: controller.signal });

// Возобновление с динамическим содержимым во время запроса
const resumeStream = await resume(<App />, postponed);

Другие заметные изменения React 19.2:

  • Границы Suspense в SSR теперь батчируются перед показом, приводя поведение сервера в соответствие с клиентским.
  • Добавлена поддержка Web Streams для SSR в Node.js.
  • eslint-plugin-react-hooks v6 с новыми правилами для паттернов useEffectEvent.

Серверные компоненты и серверные действия

В34. Что такое серверные компоненты React (RSC)?

RSC — это компоненты, которые рендерятся исключительно на сервере, производя HTML или сериализованное дерево компонентов, отправляемое клиенту. Они не влияют на размер JavaScript-бандла и могут напрямую обращаться к базам данных, файловым системам и секретам:

// app/page.jsx — серверный компонент (без "use client")
async function ProductPage({ id }) {
  const product = await db.products.findById(id); // Прямой доступ к БД
  return <ProductDetails product={product} />;
}

Ключевые свойства:

  • Нельзя использовать useState, useEffect или API браузера.
  • Можно использовать async/await на уровне компонента.
  • Можно импортировать и рендерить клиентские компоненты.
  • Клиентские компоненты не могут импортировать серверные компоненты (только оборачивать их как children).

В35. Что такое серверные действия (Server Actions)?

Серверные действия — это асинхронные функции, помеченные директивой "use server", которые выполняются на сервере при вызове с клиента, позволяя отправлять формы и выполнять мутации без ручного создания API-маршрутов:

// actions.js
"use server";
export async function createPost(formData) {
  await db.posts.create({ title: formData.get("title") });
  revalidatePath("/posts");
}

// Клиентский компонент
import { createPost } from "./actions";
<form action={createPost}>
  <input name="title" />
  <button type="submit">Create</button>
</form>

⚠️ Примечание по безопасности (2025): CVE-2025-55182 выявил критические уязвимости RCE в серверных действиях React, затрагивающие версии React 19.0.0–19.2.2. При использовании серверных действий в production убедитесь, что вы используете React 19.0.4+ / 19.1.4+ / 19.2.3+. Также обновите Next.js до исправленной версии (14.2.35, 15.2.8 или 16.0.10+ в зависимости от вашей линейки версий).

В36. В чём разница между серверными и клиентскими компонентами?

Серверный компонент Клиентский компонент
Рендеринг Только сервер Клиент (и SSR)
Размер бандла JS не отправляется Включён в бандл
Состояние/хуки ❌ Не поддерживаются ✅ Поддерживаются
Доступ к БД/файлам ✅ Прямой ❌ Невозможен
Директива (по умолчанию в App Router) "use client" в начале
Интерактивность

Конкурентный React

В37. Что такое конкурентный React?

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

Возможности, обеспечиваемые конкурентностью:

  • useTransition и useDeferredValue
  • Автоматическое батчирование (все обновления состояния в асинхронных колбэках теперь батчируются)
  • <Suspense> с серверной потоковой передачей
  • API startTransition
  • <Activity /> (React 19.2) для скрытого UI с пониженным приоритетом

В38. Что такое автоматическое батчирование в React 18+?

React 18 батчирует все обновления состояния — даже внутри setTimeout, Promise и нативных обработчиков событий — в один повторный рендер по умолчанию. Ранее батчились только обновления внутри обработчиков событий React:

// React 18: эти два setState вызывают ОДИН повторный рендер
setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
}, 1000);

Используйте flushSync из react-dom, чтобы отключить батчирование, когда это необходимо.


Redux и современные инструменты управления состоянием

В39. Что такое Redux и актуален ли он в 2026 году?

Redux — это предсказуемый контейнер состояния, основанный на едином хранилище, чистых функциях-редукторах и однонаправленном потоке данных. Он остаётся востребованным для крупных приложений со сложным общим состоянием. В 2026 году Redux Toolkit (RTK) является обязательным стандартом для Redux — createSlice, createAsyncThunk и RTK Query заменяют ручные создатели действий, редукторы и паттерны загрузки данных.

// Слайс Redux Toolkit
const counterSlice = createSlice({
  name: "counter",
  initialState: { value: 0 },
  reducers: {
    increment: state => { state.value += 1; }, // Immer обеспечивает неизменяемость
    reset: state => { state.value = 0; },
  },
});

В40. Какие альтернативы Redux популярны в 2026 году?

  • Zustand — минималистичное хранилище на основе хуков; без бойлерплейта; самый популярный легковесный вариант. (Подробнее: Zustand)
  • Jotai — атомарная модель состояния, вдохновлённая Recoil.
  • TanStack Query (React Query) — управление состоянием сервера; кэширование, фоновое обновление, оптимистичные обновления. (Подробнее: TanStack Query)
  • Valtio — состояние на основе прокси с мутациями.
  • Context + useReducer — встроенные средства, достаточные для локального состояния среднего масштаба.

Распространённый паттерн 2026 года: TanStack Query для серверного/асинхронного состояния + Zustand для UI/клиентского состояния, заменяющий Redux в большинстве некорпоративных приложений.

В41. Что такое RTK Query?

RTK Query — это мощный слой для загрузки данных и кэширования, встроенный в Redux Toolkit. Он автоматически генерирует хуки для API-эндпоинтов, обрабатывает кэширование, дедупликацию и инвалидацию кэша:

const api = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: "/api" }),
  endpoints: builder => ({
    getUser: builder.query({ query: id => `/users/${id}` }),
    updateUser: builder.mutation({ query: body => ({ url: "/users", method: "PATCH", body }) }),
  }),
});

export const { useGetUserQuery, useUpdateUserMutation } = api;

React Router v7

В42. Что нового в React Router v7?

React Router v7 (выпущен в 2024) объединился с Remix, став полноценным full-stack фреймворком. Ключевые возможности:

  • Режим фреймворка — полноценный SSR в стиле Remix, загрузчики (loaders), действия (actions), маршрутизация на основе файловой структуры.
  • Режим библиотеки — традиционная клиентская SPA-маршрутизация.
  • Типобезопасные маршруты — автоматически генерируемые TypeScript-типы для параметров маршрутов и данных загрузчиков.
  • Предзагрузка <Link> — предварительная загрузка данных маршрута при наведении/фокусе.
// Определение маршрута v7
export async function loader({ params }) {
  return await getUser(params.id);
}

export default function UserPage() {
  const user = useLoaderData();
  return <h1>{user.name}</h1>;
}

В43. Как обрабатывать защищённые маршруты в React Router v7?

function ProtectedRoute({ children }) {
  const { user } = useAuth();
  if (!user) return <Navigate to="/login" replace />;
  return children;
}

// В конфигурации маршрутов
{ path: "/dashboard", element: <ProtectedRoute><Dashboard /></ProtectedRoute> }

Context API

В44. Что такое React Context API и когда его следует использовать?

Context предоставляет способ передачи значений по дереву компонентов без пробрасывания пропсов. Лучше всего подходит для низкочастотных обновлений — тема, локаль, аутентифицированный пользователь, флаги функций. Для высокочастотных обновлений (например, позиция мыши, состояние формы) используйте внешние менеджеры состояния.

const ThemeContext = createContext("light");

function App() {
  return (
    <ThemeContext value="dark">  {/* React 19: без .Provider */}
      <Layout />
    </ThemeContext>
  );
}

function Button() {
  const theme = use(ThemeContext); // React 19: use() вместо useContext()
  return <button className={`btn btn--${theme}`}>Click</button>;
}

В React 19 <ThemeContext value="dark"> заменяет <ThemeContext.Provider value="dark">. Обе формы работают, но предпочитается новая сокращённая запись.


Обработка ошибок

В45. Как обрабатывать ошибки в современном React?

  • Границы ошибок (Error Boundaries) — перехватывают ошибки рендеринга в классовых компонентах (или через библиотеку react-error-boundary).
  • React 19 use() + Suspense — отклонённые Promise перехватываются ближайшей <ErrorBoundary>.
  • Состояние ошибки действияuseActionState предоставляет состояние ошибки из серверных действий.
  • try/catch в обработчиках событий — границы ошибок их не перехватывают; обрабатывайте явно.
  • Owner Stack (React 19.1, только dev-режим)captureOwnerStack() улучшает оверлеи ошибок трассировкой владения компонентами.
import { ErrorBoundary } from "react-error-boundary";

<ErrorBoundary fallback={<ErrorFallback />} onError={logToSentry}>
  <DataComponent />
</ErrorBoundary>

Стилизация компонентов в React

В46. Каковы основные подходы к стилизации в React в 2026 году?

  • CSS-модули — локально изолированный CSS, нулевые накладные расходы в runtime, хэширование имён классов на этапе сборки.
  • Tailwind CSS v4 — утилитарные классы прямо в JSX; v4 использует CSS-нативный движок без JS-конфигурационного файла.
  • CSS-in-JS (styled-components, Emotion) — динамические стили в JS; накладные расходы в runtime, но мощные возможности для темизации.
  • CSS-in-JS без runtime (Vanilla Extract, Panda CSS) — стили на TypeScript, компилируемые на этапе сборки.
  • Обычный CSS с @layer и вложенностью — всё более жизнеспособный вариант благодаря улучшениям нативного CSS.
// CSS-модули
import styles from "./Button.module.css";
<button className={styles.primary}>Click</button>

// Tailwind v4
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Click
</button>

В47. Как работает темизация в styled-components?

const theme = { colors: { primary: "oklch(55% 0.2 250)", text: "#111" } };

<ThemeProvider theme={theme}>
  <App />
</ThemeProvider>

const Button = styled.button`
  background: ${props => props.theme.colors.primary};
  color: white;
`;

Порталы

В48. Что такое порталы React?

Порталы рендерят вывод компонента в другой DOM-узел, отличный от родительского, сохраняя его в дереве компонентов React (события по-прежнему всплывают как обычно):

function Modal({ children, isOpen }) {
  if (!isOpen) return null;
  return createPortal(
    <div className="modal-overlay">
      <div className="modal-content">{children}</div>
    </div>,
    document.getElementById("modal-root")
  );
}

Используются для модальных окон, подсказок, выпадающих меню и любых оверлеев, которым нужно выйти за пределы CSS-контекстов overflow: hidden или стекового контекста z-index. В 2026 году нативный HTML-элемент <dialog> и Popover API обрабатывают многие из этих случаев нативно, без порталов.


Тестирование в React

В49. Какой рекомендуемый стек для тестирования в 2026 году?

  • Vitest — быстрый раннер модульных/интеграционных тестов (нативный для Vite); в значительной степени заменил Jest в новых проектах.
  • React Testing Library (RTL) — тестирование с точки зрения пользователя; запросы по роли, метке, тексту.
  • Playwright — сквозное (E2E) тестирование в браузере; предпочитается перед Cypress в новых проектах.
  • MSW (Mock Service Worker) — мокирование API на сетевом уровне как для тестов, так и для разработки.

В50. Как написать модульный тест с React Testing Library?

import { render, screen, fireEvent } from "@testing-library/react";
import Counter from "./Counter";

test("increments count on click", () => {
  render(<Counter />);
  const button = screen.getByRole("button", { name: /increment/i });
  fireEvent.click(button);
  expect(screen.getByText("Count: 1")).toBeInTheDocument();
});

В51. Как тестировать асинхронную загрузку данных?

import { render, screen } from "@testing-library/react";
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";

const server = setupServer(
  http.get("/api/user", () => HttpResponse.json({ name: "Alice" }))
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

test("displays user name after fetch", async () => {
  render(<UserProfile />);
  expect(await screen.findByText("Alice")).toBeInTheDocument();
});

В52. Когда следует использовать snapshot-тестирование?

Snapshot-тесты фиксируют отрендеренный вывод компонента и уведомляют о непредвиденных изменениях. Они наиболее полезны для стабильных презентационных компонентов. Избегайте их для часто изменяемых компонентов — устаревшие snapshot'ы создают ложную уверенность. Предпочитайте тестирование поведения, а не структуры.


Оптимизация производительности

В53. Что такое React.memo и когда его следует использовать?

React.memo — это HOC, который предотвращает повторный рендер функционального компонента, если его пропсы не изменились (поверхностное сравнение):

const ExpensiveList = React.memo(function List({ items }) {
  return items.map(item => <Item key={item.id} data={item} />);
});

С стабильным React Compiler (2025), React.memo в значительной степени автоматизирован в новых проектах. В React 18 без компилятора применяйте его к компонентам, которые дороги для рендеринга, получают стабильные пропсы и часто перерисовываются из-за обновлений родителя.

В54. Что такое разделение кода (code splitting) и как оно реализуется?

Разделение кода разбивает бандл на более мелкие части, загружаемые по требованию, сокращая время начальной загрузки: (Подробнее: React Suspense — разделение кода)

const Dashboard = lazy(() => import("./Dashboard"));

function App() {
  return (
    <Suspense fallback={<Spinner />}>
      <Dashboard />
    </Suspense>
  );
}

Разделение на уровне маршрутов с React Router — самая эффективная стратегия. Разделение на уровне компонентов уместно для тяжёлых редакторов, графиков или модальных окон.

В55. Как обеспечить производительность при работе с большими списками?

Используйте виртуализацию для рендеринга только видимых строк, что значительно сокращает количество DOM-узлов:

import { useVirtualizer } from "@tanstack/react-virtual";

function VirtualList({ items }) {
  const parentRef = useRef(null);
  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 40,
  });

  return (
    <div ref={parentRef} style={{ height: "500px", overflow: "auto" }}>
      <div style={{ height: `${virtualizer.getTotalSize()}px`, position: "relative" }}>
        {virtualizer.getVirtualItems().map(row => (
          <div key={row.key} style={{ position: "absolute", top: row.start }}>
            {items[row.index].name}
          </div>
        ))}
      </div>
    </div>
  );
}

В56. Как <Activity /> улучшает производительность скрытого UI?

В отличие от условного рендеринга ({isVisible && <Panel />}), который полностью размонтирует и повторно монтирует компоненты, <Activity mode="hidden"> сохраняет дерево компонентов в памяти, откладывает обновления и размонтирует эффекты — так что, когда пользователь снова показывает его, не требуется повторная инициализация и навигация ощущается мгновенной. Это рекомендуемый паттерн для интерфейсов с вкладками, боковых панелей и предварительного рендеринга ожидаемых маршрутов.


Серверный рендеринг и потоковая передача

В57. Что такое серверный рендеринг (SSR) и какие фреймворки его поддерживают?

SSR рендерит компоненты React на сервере в HTML перед отправкой клиенту, улучшая Time to First Byte (TTFB) и SEO. Фреймворки: Next.js (самый популярный), React Router v7 / Remix, Astro (частичная гидратация), TanStack Start (на базе RSC).

В58. Что такое потоковый SSR и как Suspense его обеспечивает?

Потоковый SSR отправляет HTML в браузер прогрессивно, по мере готовности, а не ждёт полной загрузки всей страницы. Границы <Suspense> выступают точками разделения потока: (Подробнее: React Suspense)

// Next.js App Router
export default async function Page() {
  return (
    <main>
      <Header />           {/* Отправляется немедленно */}
      <Suspense fallback={<Skeleton />}>
        <SlowDataComponent /> {/* Потоковая передача при разрешении данных */}
      </Suspense>
    </main>
  );
}

React 19.2 добавил батчирование границ Suspense для SSR — границы теперь батчируют свои показы, чтобы серверное потоковое поведение соответствовало клиентскому рендерингу, предотвращая появление контента по частям.

В59. Что такое частичный предварительный рендеринг и как он работает в React 19.2?

Частичный предварительный рендеринг (PPR) позволяет предварительно отрендерить статическую оболочку страницы на CDN и возобновить рендеринг динамических частей позже, во время запроса:

// Шаг 1: Предварительный рендеринг статической оболочки
const { prelude, postponed } = await prerender(<App />, {
  signal: controller.signal,
});
// Отправить prelude на CDN

// Шаг 2: Возобновление с динамическим содержимым во время запроса
const stream = await resume(<App />, postponed);
// Отправить stream в браузер

Это даёт лучшее из обоих миров — кэшированный на CDN статический HTML и свежий динамический контент — без компромиссов традиционного ISR.

В60. Что такое гидратация и что такое «частичная гидратация»?

Гидратация — это процесс присоединения обработчиков событий React к HTML, отрендеренному на сервере, на клиенте. Полная гидратация гидратирует всю страницу. Частичная гидратация (используется в Astro и появляющаяся в React через RSC) гидратирует только интерактивные компоненты, оставляя статические части как обычный HTML — что значительно сокращает клиентский JavaScript.


Инструменты сборки и развёртывание

В61. Какие инструменты сборки используются с React в 2026 году?

  • Vite — доминирующий выбор для новых SPA и библиотек; быстрый HMR, нативный ESM.
  • Turbopack — наследник Webpack на Rust, интегрированный в Next.js 15.
  • esbuild — сверхбыстрый бандлер; используется внутри Vite.
  • Webpack 5 — всё ещё распространён в крупных корпоративных проектах со сложными конфигурациями.
  • Rspack — совместимый с Webpack бандлер на Rust от ByteDance.

Официальная рекомендация (2025): Команда React официально прекратила поддержку Create React App и рекомендует новым проектам использовать фреймворк (Next.js, React Router v7) или инструмент сборки, такой как Vite, Parcel или RSBuild.

В62. Что такое React Compiler и готов ли он к production?

React Compiler (ранее React Forget) достиг первого стабильного релиза в 2025 году. Это инструмент этапа сборки, который автоматически мемоизирует компоненты и значения React, устраняя необходимость в ручном useMemo, useCallback и React.memo. Доступен как плагин для Babel/SWC.

# Установка
npm install babel-plugin-react-compiler

# babel.config.js
plugins: [["babel-plugin-react-compiler", {}]]

В63. Какие стратегии развёртывания и CI/CD используются для React-приложений?

  • Vercel / Netlify — развёртывание без конфигурации с URL-адресами превью для каждого PR; нативная поддержка Next.js.
  • GitHub Actions / GitLab CI — запуск тестов, линтинга и сборок при каждом push.
  • Docker — контейнеризированные развёртывания для собственной инфраструктуры.
  • Сине-зелёные и canary-развёртывания — используйте флаги функций платформы (LaunchDarkly, PostHog) или разделение трафика на уровне инфраструктуры.
  • Edge-развёртывание — развёртывание React/Next.js приложений на edge-сети CDN (Vercel Edge, Cloudflare Workers) для минимальной задержки.

TypeScript и React

В64. Как типизировать компоненты и хуки React в TypeScript?

// Интерфейс пропсов компонента
interface ButtonProps {
  label: string;
  variant?: "primary" | "secondary";
  onClick: () => void;
}

function Button({ label, variant = "primary", onClick }: ButtonProps) {
  return <button className={`btn--${variant}`} onClick={onClick}>{label}</button>;
}

// Типизация useState
const [user, setUser] = useState<User | null>(null);

// Типизация useRef
const inputRef = useRef<HTMLInputElement>(null);

// Типизация обработчиков событий
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  setValue(e.target.value);
};

// Типизация useActionState (React 19)
const [state, action, isPending] = useActionState<FormState, FormData>(serverAction, null);

В65. В чём разница между React.FC и обычным объявлением функции для компонентов?

React.FC (или React.FunctionComponent) — это дженерик-тип, который неявно типизирует children и displayName. В 2026 году React.FC в целом не рекомендуется в пользу явной типизации пропсов, поскольку React.FC исторически неявно включал children (удалено в типах React 18) и добавляет излишний шум. Вместо него используйте обычные объявления функций с явными интерфейсами.


Доступность в React

В66. Каковы лучшие практики обеспечения доступности в React?

  • Используйте семантические HTML-элементы (<button>, <nav>, <main>) вместо <div> для интерактивного содержимого.
  • Явно управляйте фокусом после обновлений динамического содержимого (модальные окна, смена маршрутов).
  • Используйте атрибуты aria-*, когда семантического HTML недостаточно.
  • Тестируйте с eslint-plugin-jsx-a11y в вашей конфигурации линтинга.
  • Тестируйте с помощью скринридера (VoiceOver, NVDA) и дерева доступности в DevTools.
  • Используйте регионы aria-live для объявлений динамического содержимого.
  • При использовании <Activity /> убедитесь, что скрытое содержимое не доступно для фокуса в режиме hidden; API обрабатывает это, но проверяйте тестированием со скринридером.
// Управление фокусом в модальном окне
useEffect(() => {
  if (isOpen) closeButtonRef.current?.focus();
}, [isOpen]);

Паттерны проектирования и структура файлов

В67. Какие паттерны проектирования компонентов используются в React?

Основные паттерны:

  • Композиция — построение сложного UI через вложение компонентов (children, именованные слоты).
  • Compound Components — составные компоненты, разделяющие состояние через Context (Radix UI, Headless UI). (Подробнее: Паттерны проектирования)
  • Render Props — передача функции как пропса для инверсии контроля над рендерингом.
  • Custom Hooks — основной паттерн переиспользования логики в современном React.
  • Container / Presentational — разделение на «умные» (данные, логика) и «глупые» (только UI) компоненты.
  • State Reducer — передача контроля над обновлением состояния потребителю.
  • Control Props — поддержка управляемого и неуправляемого режимов (как <input value> vs <input defaultValue>).

В68. Как организовать структуру файлов в React/Next.js проекте?

Основные подходы:

  • По типуcomponents/, hooks/, services/, utils/ (для маленьких проектов).
  • По фичеfeatures/auth/, features/products/ (всё, что относится к фиче, в одном месте).
  • Feature-Sliced Design (FSD)app/, pages/, widgets/, features/, entities/, shared/ (строгая иерархия слоёв).
  • Domain-driven — группировка по бизнес-домену с разделением на domains/, infrastructure/, application/, presentation/.

В Next.js App Router структура частично навязана файловой системой: app/ для маршрутов, components/ для UI, lib/ для утилит и API-клиента. (Подробнее: Структура файлов)

В68.1. Как классические паттерны GoF применяются во Frontend (React и Vue)?

Четыре ключевых паттерна из GoF адаптируются под реалии frontend-разработки:

  • Абстрактная фабрика — фабрики компонентов через Context/provide-inject для темизации, мультиплатформенности и white-label решений.
  • Декоратор — HOC, хуки, JSX-обёртки в React; директивы, composables, обёрточные компоненты во Vue.
  • Синглтон — ES-модули, сторы (Zustand, Pinia), Context-провайдеры как единый источник истины.
  • Наблюдатель — встроенная реактивность фреймворков (useState, ref/reactive), event bus, useSyncExternalStore.

(Подробнее: Классические паттерны GoF во Frontend)


Классические паттерны GoF во Frontend (React и Vue)

В68.1. Как классические паттерны GoF (Абстрактная фабрика, Декоратор, Синглтон, Наблюдатель) применяются во Frontend?

Четыре паттерна из книги GoF адаптируются под React и Vue:

  • Абстрактная фабрика — создание семейств связанных компонентов (темизация, мультиплатформенность). В React — через Context + фабричные объекты, во Vue — через provide/inject + динамические компоненты.
  • Декоратор — динамическое расширение функциональности. В React — HOC, хуки, JSX-обёртки; во Vue — директивы, composables, обёрточные компоненты.
  • Синглтон — единственный экземпляр объекта. В frontend — ES-модули, Zustand/Pinia сторы, Context-провайдеры. Опасен при SSR из-за «протекания» состояния между запросами.
  • Наблюдатель — автоматическое уведомление при изменении состояния. Встроен в реактивность обоих фреймворков: useState/useReducer в React, ref/reactive/watch во Vue.

(Подробнее: Классические паттерны GoF во Frontend)


Безопасность в React и Next.js

В69. Как React защищает от XSS-атак?

React автоматически экранирует все значения в JSX-выражениях {variable} и атрибутах. Скрипты, вставленные через строки, не выполняются.

Опасные места:

  • dangerouslySetInnerHTML — требует санитизации через DOMPurify.
  • URL-атрибуты (href, src) — валидация протокола (javascript: XSS).
  • Прямой доступ к DOM через ref.current.innerHTML.
  • Third-party библиотеки (markdown-парсеры) без санитизации.

(Подробнее: Безопасность — XSS)

В70. Как защитить Server Actions в Next.js?

Server Actions выполняются на сервере, но принимают данные от клиента. Обязательно:

  1. Валидация входных данных — Zod-схемы для всех параметров.
  2. Проверка авторизацииawait auth() в каждом действии.
  3. Rate limiting — ограничение частоты вызовов.
  4. Обновление версий — CVE-2025-55182 (RCE в Server Actions) исправлен в React 19.0.4+ / 19.1.4+ / 19.2.3+.

(Подробнее: Безопасность Server Actions)

В71. Как безопасно работать с секретами в Next.js?

  • Переменные без префикса NEXT_PUBLIC_ доступны только на сервере (Server Components, API Routes, middleware).
  • Переменные с префиксом NEXT_PUBLIC_ попадают в клиентский бандл — храните только публичные ключи.
  • .env.local не коммитится в git.
  • Для production используйте Vercel Environment Variables, AWS Secrets Manager, Doppler.

(Подробнее: Безопасная работа с секретами)


WebSocket в React и Next.js

В72. Когда использовать WebSocket вместо HTTP?

WebSocket нужен для полнодуплексной связи в реальном времени:

  • Чат и мессенджеры
  • Коллаборативные редакторы
  • Торговые платформы (обновления цен)
  • Мультиплеерные игры
  • Push-уведомления

Для односторонней передачи (сервер → клиент) проще использовать Server-Sent Events (SSE) — автоматическое переподключение, работа через обычный HTTP. Для запрос-ответ — обычный REST.

(Подробнее: WebSocket — когда использовать)

В73. Как интегрировать WebSocket с React?

Базовый подход — хук useWebSocket, инкапсулирующий:

  • Установку и закрытие соединения в useEffect
  • Обработку переподключений (exponential backoff)
  • Очередь сообщений для отправки
  • Интеграцию с Zustand/TanStack Query для синхронизации с глобальным состоянием

В Next.js WebSocket-соединение устанавливается только на клиенте (в useEffect). Для production используйте отдельный WebSocket-сервер или managed-сервисы (Pusher, Ably, Supabase Realtime).

(Подробнее: WebSocket в React)


Мониторинг через Sentry

В74. Что такое Sentry и зачем он нужен?

Sentry — платформа мониторинга ошибок и производительности в реальном времени. Отслеживает:

  • Exceptions — неперехваченные ошибки JavaScript
  • Performance issues — медленные загрузки страниц, API-запросы
  • Releases — какие ошибки появились в новых версиях
  • User impact — сколько пользователей затронуто

Без мониторинга вы узнаёте о проблемах из жалоб пользователей — часто слишком поздно. (Подробнее: Sentry)

В75. Как настроить Sentry в Next.js?

npx @sentry/wizard@latest -i nextjs

Wizard автоматически создаст sentry.client.config.js, sentry.server.config.js, sentry.edge.config.js и настроит next.config.js с withSentryConfig. Ключевые параметры: tracesSampleRate (performance), replaysSessionSampleRate (Session Replay), release (версия приложения). (Подробнее: Установка Sentry)


React Native — введение

В76. Что такое React Native и чем он отличается от React?

React Native — фреймворк для создания нативных мобильных приложений (iOS и Android) на React. Код пишется на JavaScript/TypeScript, но рендеринг происходит в нативные UI-компоненты (UIKit, Android Views) — не WebView.

Ключевые отличия от React:

  • Нет HTML/CSS — вместо этого <View>, <Text>, StyleSheet
  • Нет onClick — вместо этого onPress
  • Нет <form>, <input> — вместо этого <TextInput>
  • Навигация через React Navigation / Expo Router
  • Доступ к нативным модулям (камера, GPS, push)

Всё остальное (хуки, состояние, Context, Zustand, TanStack Query) работает как в React. (Подробнее: React Native)

В77. Expo или Bare CLI?

В 2026 году Expo — рекомендуемый способ начать React Native проект. Expo даёт:

  • Не нужен Xcode / Android Studio для разработки
  • EAS Build — облачная сборка
  • EAS Update — OTA-обновления без ревью сторов
  • Expo Router — файловая маршрутизация (как Next.js)
  • Готовые модули (камера, геолокация, уведомления)

Bare CLI нужен только если требуется полный контроль над нативным кодом. (Подробнее: Expo vs Bare)


Progressive Web Apps (PWA)

В78. Что такое PWA и какие три компонента нужны?

PWA — веб-приложение, работающее как нативное: офлайн, push-уведомления, установка на домашний экран.

Три столпа:

  1. HTTPS — обязательно (кроме localhost)
  2. Web App Manifest — JSON-файл с иконками, темой, display: standalone
  3. Service Worker — перехватывает запросы, кэширует ресурсы, работает офлайн

PWA не нужен App Store, обновляется автоматически, весит несколько MB вместо 100+ MB нативного приложения. (Подробнее: PWA)

В79. Какие стратегии кэширования используются в Service Workers?

  • Cache First — отдаёт из кэша, если нет — загружает из сети (статические ресурсы)
  • Network First — загружает из сети, если нет — отдаёт из кэша (API, динамический контент)
  • Stale While Revalidate — отдаёт из кэша сразу, обновляет в фоне (быстро + свежо)
  • Cache Only — только из кэша (версионированные файлы)

Workbox упрощает реализацию: new CacheFirst({ cacheName: "images" }). (Подробнее: Стратегии кэширования)


Тестирование и LLM

В80. Какой стек тестирования рекомендуется в 2026 году?

  • Vitest — раннер модульных/интеграционных тестов (нативный для Vite, заменил Jest)
  • React Testing Library — тестирование с точки зрения пользователя (getByRole, getByLabelText)
  • Playwright — E2E-тестирование (предпочитается перед Cypress)
  • MSW — мокирование API на сетевом уровне (для тестов и разработки)

Главный принцип: тестируйте поведение, а не реализацию. Используйте screen.getByRole() вместо container.querySelector(). (Подробнее: Тестирование)

В81. Как использовать LLM для написания тестов?

LLM (ChatGPT, Claude, Copilot, Cursor) помогают:

  • Генерация тестов — опишите функцию, LLM напишет тесты с edge cases
  • Генерация edge cases — спросите «какие edge cases нужно протестировать?»
  • Генерация тестовых данных — фабрики, моки, fixtures
  • Ревью тестов — попросите проанализировать существующие тесты
  • Написание E2E-сценариев — опишите user flow, LLM сгенерирует Playwright-тест

Промпт для генерации: «Напиши тесты для функции X на Vitest. Функция принимает Y, возвращает Z. Учитывай edge cases.» (Подробнее: LLM для тестирования)


Дополнительные ресурсы 📚

Подробная документация по Suspense доступна в docs/react/react_suspense.md — механизм работы, сценарии использования, примеры кода и лучшие практики.

Официальная документация

  • React Official Docs — полностью переписана; hooks-first, исчерпывающая.
  • React Blog — официальные обновления версий, включая React 19.1 и 19.2.
  • React Versions — список изменений всех релизов.

Фреймворки

  • Next.js — самый популярный React-фреймворк для SSR/RSC.
  • React Router v7 / Remix — полноценный React с маршрутизацией на основе файловой структуры.
  • TanStack Start — новый фреймворк с поддержкой RSC.

Управление состоянием

Тестирование

  • Vitest — быстрый раннер модульных тестов.
  • React Testing Library
  • Playwright — E2E-тестирование.
  • MSW — мокирование API на сетевом уровне.

Производительность

Обучение

Архитектура и паттерны

Безопасность

  • OWASP Top 10 — основные веб-уязвимости.
  • DOMPurify — санитизация HTML.
  • Helmet.js — HTTP-заголовки безопасности (Express).

Мониторинг

  • Sentry — мониторинг ошибок и производительности.
  • LogRocket — запись сессий пользователей.
  • OpenReplay — open-source session replay.

Мобильная разработка

  • React Native — нативные мобильные приложения на React.
  • Expo — managed workflow для React Native.
  • Expo Router — файловая маршрутизация.

PWA и офлайн

Что отслеживать (горизонт 2026)

  • Расширение режимов <Activity /> — дополнительные режимы помимо visible/hidden, запланированные для будущих релизов.
  • Внедрение React Compiler — более широкое распространение в экосистеме, устраняющее ручное мемоизирование во всех основных фреймворках.
  • Частичный предварительный рендеринг в масштабе — PPR matures в Next.js как стратегия развёртывания по умолчанию.
  • Серверные компоненты React вне Next.js — TanStack Start и Parcel развивают поддержку RSC.
  • React Foundation — анонсирована в 2025; новая структура управления для долгосрочного развития React.
  • Расширение хука use() — более глубокая интеграция с паттернами асинхронного рендеринга и координацией Suspense.

About

A private repository to learn React / Next

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors