React + ChatGPT в 2026: как я перестал писать шаблонный код и начал проектировать архитектуру
За последние два года React-разработка изменилась сильнее, чем за предыдущие пять. React Server Components, Server Actions, компилятор React Compiler (стабильный релиз состоялся в 2025 году), переход многих команд на Vite и Turbopack — всё это сделало рутинную работу ещё более рутинной, а архитектурные решения — ещё более важными. И именно здесь LLM-ассистенты превратились из «игрушки для генерации boilerplate» в полноценного партнёра по инженерным решениям.
По данным Stack Overflow Developer Survey 2025, React остаётся самым используемым веб-фреймворком (используется у большинства респондентов, пишущих на фронтенде), а инструменты на базе LLM вошли в топ-5 самых применяемых технологий. Но есть нюанс: качество результата напрямую зависит от качества промта. Плохой промт даёт generic-код из туториала 2019 года с классовыми компонентами и componentWillMount.
В этой подборке — 12 сценариев, которые я и мои коллеги реально используем в продакшене. Каждый промт проверен на живых проектах, каждый пример — рабочий код. Промты разбиты на три уровня: базовые (для быстрого старта), продвинутые (для оптимизации и рефакторинга) и экспертные (для архитектуры и деплоя).
Базовый уровень: где LLM экономит часы
1. Генерация компонента с типизацией и доступностью
Задача: быстро создать переиспользуемый UI-компонент с корректными пропсами, ARIA-атрибутами и поддержкой клавиатурной навигации.
Промт:
Ты — senior React-разработчик. Создай компонент Button на TypeScript.
Требования:
- Поддержка вариантов: primary, secondary, ghost
- Пропсы: variant, size, isLoading, disabled, onClick, children
- Корректные ARIA-атрибуты (aria-busy при загрузке, aria-disabled)
- Нативная поддержка клавиатуры (Enter, Space)
- Без внешних UI-библиотек
- Используй React.forwardRef для передачи ref
Дай полный код + пример использования.
Пример результата:
import { forwardRef, ButtonHTMLAttributes } from 'react';
type Variant = 'primary'
| 'secondary' | 'ghost';
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: Variant;
isLoading?: boolean;
}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ variant = 'primary', isLoading, disabled, children, ...rest }, ref) => {
const isDisabled = disabled || isLoading;
return (
<button
ref={ref}
aria-busy={isLoading}
aria-disabled={isDisabled}
disabled={isDisabled}
className={`btn btn--${variant}`}
{...rest}
>
{isLoading ? 'Загрузка…' : children}
</button>
);
}
);
Button.displayName = 'Button';
Почему работает: промт задаёт роль, ограничения и явно требует ARIA. Без этого LLM часто забывает про aria-busy и forwardRef.
2. Кастомный хук для работы с API
Задача: написать хук useFetch с отменой запроса, обработкой состояний и типизацией.
Промт:
Напиши хук useFetch<T> на TypeScript для React 18+.
Требования:
- Отмена запроса через AbortController при размонтировании
- Состояния: data, error, isLoading
- Типизация через дженерик
- Без внешних зависимостей (не использовать react-query)
- Пример использования с типизированным ответом
Пример результата:
import { useEffect, useState } from 'react';
export function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [error, setError] = useState<Error | null>(null);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
const controller = new AbortController();
setLoading(true);
fetch(url, { signal: controller.signal })
.then((r) => r.json())
.then(setData)
.catch((e) => e.name !== 'AbortError' && setError(e))
.finally(() => setLoading(false));
return () => controller.abort();
}, [url]);
return { data, error, isLoading };
}
Важно: в 2026 году для продакшена стоит рассмотреть TanStack Query — но для прототипа или небольшого проекта хук с AbortController полностью оправдан.
3. Перевод классового компонента в функциональный
Задача: миграция легаси-кода без изменения поведения.
Промт:
Перепиши этот классовый компонент в функциональный с хуками.
Сохрани поведение: componentDidMount, componentDidUpdate по пропсу id, очистка в componentWillUnmount.
Не меняй имена пропсов. Используй useEffect с корректными зависимостями.
[вставь код компонента]
Совет: всегда просите LLM объяснить зависимости useEffect — это самая частая причина багов при миграции.
Продвинутый уровень: оптимизация и рефакторинг
4. Оптимизация ререндеров через мемоизацию
Задача: найти причины лишних ререндеров и предложить решения.
Промт:
Проанализируй этот компонент на предмет лишних ререндеров.
Предложи:
1. Где применить React.memo, useMemo, useCallback
2. Есть ли проблемы с контекстом (пересоздание значения)
3. Не нарушены ли правила мемоизации
Дай исправленный код с комментариями.
[вставь код]
Пример ответа: LLM часто указывает на типичную ошибку — передачу инлайн-объекта в провайдер контекста:
// Плохо: значение пересоздаётся каждый рендер
<ThemeContext.Provider value={{ theme, setTheme }}>
// Хорошо: мемоизация значения
const ctx = useMemo(() => ({ theme, setTheme }), [theme]);
<ThemeContext.Provider value={ctx}>
5. Рефакторинг логики в кастомные хуки
Задача: вынести повторяющуюся логику из компонентов.
Промт:
Найди в этих трёх компонентах повторяющуюся логику работы с localStorage.
Вынеси её в кастомный хук useLocalStorage<T> с поддержкой SSR (проверка typeof window).
Покажи diff: что убрать из компонентов и что добавить.
Пример результата:
export function useLocalStorage<T>(key: string, initial: T) {
const [value, setValue] = useState<T>(() => {
if (typeof window === 'undefined') return initial;
const raw = window.localStorage.getItem(key);
return raw ? (JSON.parse(raw) as T) : initial;
});
useEffect(() => {
window.localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue] as const;
}
6. Аудит производительности бандла
Задача: снизить размер бандла.
Промт:
Вот вывод `vite build --analyze`. Предложи:
1. Что разбить через dynamic import (React.lazy)
2. Какие библиотеки заменить на более лёгкие аналоги
3. Где применить tree-shaking
Оцени примерную экономию в КБ.
[вставь отчёт]
Реальный кейс: замена moment.js (~290 КБ) на date-fns или dayjs — классический совет, который LLM даёт стабильно. По данным bundlephobia, dayjs весит около 2 КБ gzip против ~70 КБ у moment.
7. Написание тестов (RTL + Vitest)
Промт:
Напиши тесты для компонента [название] на Vitest + React Testing Library.
Покрой:
- Рендер с дефолтными пропсами
- Клик по кнопке вызывает onClick
- Состояние isLoading блокирует кнопку
Используй userEvent, не fireEvent.
LLM отлично справляется с генерацией тестов, но проверяйте, что он не мокает то, что не нужно мокать.
Экспертный уровень: архитектура и деплой
8. Проектирование структуры проекта
Промт:
Спроектируй структуру Feature-Sliced Design для React-приложения:
- 3 фичи: auth, cart, checkout
- Есть shared UI-кит и API-клиент
- Используется React Router v7
Дай дерево папок и объясни границы слоёв (imports только вниз).
Пример ответа:
src/
app/ # провайдеры, роутинг, глобальные стили
pages/ # композиция фич под маршрут
features/ # auth, cart, checkout
entities/ # user, product
shared/ # ui, api, lib, config
9. Server Components и границы клиента
Задача: правильно разделить server/client код.
Промт:
У меня Next.js 15 App Router. Помоги разделить компонент на Server и Client части.
Правила:
- 'use client' только там, где есть хуки или обработчики событий
- Данные грузятся на сервере
- Интерактив (кнопка лайка) — в клиентском дочернем компоненте
Покажи финальную структуру файлов.
Это критично: ошибка с 'use client' в корне дерева убивает весь смысл Server Components и увеличивает бандл.
10. Настройка CI/CD для React-приложения
Промт:
Сгенерируй GitHub Actions workflow для React + Vite:
- Триггер: push в main и PR
- Шаги: install (pnpm), lint, typecheck, test, build
- Кэш node_modules и pnpm store
- Деплой на Vercel только из main
LLM уверенно пишет YAML, но проверяйте версии actions — в 2026 году актуальны actions/checkout@v4 и actions/setup-node@v4.
11. Код-ревью и поиск антипаттернов
Промт:
Проведи код-ревью этого PR как senior React-разработчик.
Обрати внимание на:
- Правила хуков
- Утечки памяти (подписки, таймеры)
- Антипаттерны работы со state (мутации, derived state)
- Доступность
Формат: список замечаний с приоритетом (critical/major/minor).
12. Документирование компонентов
Промт:
Сгенерируй JSDoc и Storybook-стори для компонента [название].
Опиши все пропсы, дефолтные значения и edge cases.
Документация — то, что разработчики откладывают до последнего. LLM делает это за минуту.
Сравнение уровней промтов
| Уровень | Цель | Экономия времени | Риск галлюцинаций |
|---|---|---|---|
| Базовый | Генерация кода | Высокая | Низкий |
| Продвинутый | Рефакторинг, оптимизация | Средняя | Средний |
| Экспертный | Архитектура, деплой | Средняя | Высокий — нужна проверка |
Что важно помнить
Во-первых, всегда давайте контекст: версию React, стек, ограничения. Промт без контекста — это гадание. Во-вторых, проверяйте API: LLM может предложить устаревший синтаксис (например, useEffect там, где в React 19 достаточно use или Server Actions). В-третьих, для критичных решений (безопасность, платежи, авторизация) — только ручное ревью.
React-экосистема в 2026 году требует не столько умения писать код, сколько умения принимать архитектурные решения. LLM берёт на себя рутину: boilerplate, тесты, документацию, миграции. Ваша задача — задавать правильные вопросы и проверять ответы. Начните с одного-двух промтов из этой подборки на текущем проекте — и вы быстро почувствуете разницу в скорости. А если хотите системно прокачать навыки работы с AI-инструментами в разработке, посмотрите материалы нашего блога — там разбираем реальные кейсы без воды.
Комментарии