Введение
Разработка на React и Next.js — это не только написание кода, но и постоянное взаимодействие с документацией, поиск готовых решений и генерация boilerplate. С ростом популярности AI-ассистентов (ChatGPT, Claude, Copilot) умение формулировать правильные промты стало таким же важным навыком, как знание JSX или хуков. По данным опроса Stack Overflow за 2025 год, более 70% разработчиков используют AI-инструменты для генерации кода, но лишь каждый третий получает качественный результат — проблема чаще всего в неконкретных промтах.
В этой статье я собрал 15 проверенных промтов (базовые, продвинутые и экспертные), которые помогут вам ускорить разработку React/Next.js приложений: от простых компонентов до сложных страниц с SSR и оптимизацией. Каждый промт сопровождается примером результата и рекомендациями по настройке. Статья написана для разработчиков уровня Junior+ и Middle, которые хотят использовать AI как инструмент, а не как чёрный ящик.
Категория 1: Базовые промты (5 шт.)
1. Генерация функционального компонента с TypeScript
Задача: Быстро создать компонент с типизацией пропсов.
Промт:
Сгенерируй React функциональный компонент на TypeScript, который принимает props: { title: string, description?: string, onClick: () => void }. Компонент должен отображать заголовок (h2), описание (если есть) и кнопку. Используй стили через CSS-in-JS (styled-components или inline styles).
Пример результата:
import React from 'react';
interface CardProps {
title: string;
description?: string;
onClick: () => void;
}
const Card: React.FC<CardProps> = ({ title, description, onClick }) => {
return (
<div style={{ border: '1px solid #ccc', padding: '16px', borderRadius: '8px' }}>
<h2>{title}</h2>
{description && <p>{description}</p>}
<button onClick={onClick}>Click me</button>
</div>
);
};
export default Card;
Совет: Уточняйте в промте, используете ли вы TypeScript, иначе AI может сгенерировать JS-код без типов.
2. Создание формы с валидацией (React Hook Form)
Задача: Получить готовую форму с регистрацией полей и базовой валидацией.
Промт:
Напиши React компонент формы регистрации с полями: email (required, email format), password (required, minLength 6), confirmPassword (must match password). Используй библиотеку react-hook-form и yup для схемы валидации. При успешной отправке выводи alert с сообщением.
Пример результата (сокращённо):
import React from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
const schema = yup.object().shape({
email: yup.string().email('Invalid email').required('Email is required'),
password: yup.string().min(6, 'Min 6 characters').required(),
confirmPassword: yup.string().oneOf([yup.ref('password')], 'Passwords must match').required(),
});
interface FormData {
email: string;
password: string;
confirmPassword: string;
}
const RegistrationForm: React.FC = () => {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: yupResolver(schema),
});
const onSubmit = (data: FormData) => {
alert(`Registered with email: ${data.email}`);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label>Email</label>
<input {...register('email')} />
{errors.email && <p>{errors.email.message}</p>}
</div>
<div>
<label>Password</label>
<input type="password" {...register('password')} />
{errors.password && <p>{errors.password.message}</p>}
</div>
<div>
<label>Confirm Password</label>
<input type="password" {...register('confirmPassword')} />
{errors.confirmPassword && <p>{errors.confirmPassword.message}</p>}
</div>
<button type="submit">Register</button>
</form>
);
};
export default RegistrationForm;
3. Компонент списка с фильтрацией и поиском
Задача: Сгенерировать компонент, который рендерит массив данных с возможностью фильтрации по тексту.
Промт:
Создай React компонент, который принимает массив объектов { id: number, name: string, category: string }. Реализуй поиск по name (input) и фильтрацию по category (select с опциями All, Category1, Category2). Отображай отфильтрованный список в виде карточек. Используй useState.
Пример результата (ключевая часть):
const [search, setSearch] = useState('');
const [category, setCategory] = useState('All');
const filtered = data.filter(item => {
const nameMatch = item.name.toLowerCase().includes(search.toLowerCase());
const catMatch = category === 'All' || item.category === category;
return nameMatch && catMatch;
});
4. Хук useFetch для получения данных
Задача: Получить кастомный хук для работы с API.
Промт:
Напиши React хук useFetch, который принимает URL и возвращает { data, loading, error }. Используй useEffect и fetch API. Добавь поддержку отмены запроса через AbortController.
Пример результата:
import { useState, useEffect } from 'react';
function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const controller = new AbortController();
setLoading(true);
fetch(url, { signal: controller.signal })
.then(res => res.json())
.then(setData)
.catch(err => {
if (err.name !== 'AbortError') setError(err.message);
})
.finally(() => setLoading(false));
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
export default useFetch;
5. Модальное окно с анимацией
Задача: Создать переиспользуемый компонент модального окна с плавным появлением.
Промт:
Создай React компонент Modal с пропсами: isOpen, onClose, children. Реализуй анимацию появления/исчезания через CSS transition (opacity, transform). Добавь закрытие по клику на оверлей и по Escape. Используй React Portal.
Пример результата (структура):
import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
const Modal: React.FC<{ isOpen: boolean; onClose: () => void; children: React.ReactNode }> = ({ isOpen, onClose, children }) => {
useEffect(() => {
const handleEsc = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };
if (isOpen) document.addEventListener('keydown', handleEsc);
return () => document.removeEventListener('keydown', handleEsc);
}, [isOpen, onClose]);
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>,
document.body
);
};
Категория 2: Продвинутые промты (5 шт.)
6. Генерация Next.js страницы с SSR и getServerSideProps
Задача: Создать страницу с серверным рендерингом и получением данных из API.
Промт:
Напиши Next.js страницу /products, которая использует getServerSideProps для получения списка продуктов из внешнего API (например, https://fakestoreapi.com/products). Отобрази продукты в виде сетки карточек с изображением, названием и ценой. Добавь обработку ошибок и fallback UI.
Пример результата:
import { GetServerSideProps } from 'next';
import React from 'react';
interface Product {
id: number;
title: string;
price: number;
image: string;
}
interface Props {
products: Product[];
error?: string;
}
const ProductsPage: React.FC<Props> = ({ products, error }) => {
if (error) return <div>Error: {error}</div>;
return (
<div className="grid grid-cols-3 gap-4">
{products.map(p => (
<div key={p.id}>
<img src={p.image} alt={p.title} width={200} height={200} />
<h3>{p.title}</h3>
<p>${p.price}</p>
</div>
))}
</div>
);
};
export const getServerSideProps: GetServerSideProps = async () => {
try {
const res = await fetch('https://fakestoreapi.com/products');
const products = await res.json();
return { props: { products } };
} catch (err) {
return { props: { products: [], error: 'Failed to fetch' } };
}
};
export default ProductsPage;
7. Динамический маршрут Next.js с getStaticPaths
Задача: Создать статическую страницу для каждого продукта с генерацией путей.
Промт:
Создай Next.js страницу /products/[id] с getStaticPaths и getStaticProps. Используй тот же API фейковых товаров. Страница должна показывать детальную информацию о продукте (название, цена, описание, изображение). Если продукт не найден — верни 404.
Пример результата (часть):
export const getStaticPaths: GetStaticPaths = async () => {
const res = await fetch('https://fakestoreapi.com/products');
const products = await res.json();
const paths = products.map((p: Product) => ({ params: { id: p.id.toString() } }));
return { paths, fallback: false };
};
export const getStaticProps: GetStaticProps = async ({ params }) => {
const res = await fetch(`https://fakestoreapi.com/products/${params.id}`);
if (!res.ok) return { notFound: true };
const product = await res.json();
return { props: { product } };
};
8. Компонент с оптимизацией через React.memo и useMemo
Задача: Улучшить производительность компонента списка.
Промт:
Напиши React компонент ExpensiveList, который принимает массив items (с полями id, value) и отображает их в виде списка. Используй React.memo для обёртки компонента, useMemo для сортировки items по value, useCallback для функции-обработчика клика. Покажи разницу производительности с комментариями.
Пример результата:
const ExpensiveList: React.FC<{ items: Item[] }> = React.memo(({ items }) => {
const sorted = useMemo(() => [...items].sort((a, b) => a.value - b.value), [items]);
const handleClick = useCallback((id: number) => {
console.log('Clicked', id);
}, []);
return (
<ul>
{sorted.map(item => (
<li key={item.id} onClick={() => handleClick(item.id)}>{item.value}</li>
))}
</ul>
);
});
9. useContext + useReducer для глобального состояния
Задача: Реализовать управление корзиной через Context API.
Промт:
Создай контекст CartContext с провайдером, использующим useReducer. Реализуй действия: ADD_ITEM, REMOVE_ITEM, CLEAR. Каждый item имеет id, name, price, quantity. Напиши кастомный хук useCart для доступа к контексту.
Пример результата (редьюсер):
type Action =
| { type: 'ADD_ITEM'; payload: CartItem }
| { type: 'REMOVE_ITEM'; payload: number }
| { type: 'CLEAR' };
const cartReducer = (state: CartItem[], action: Action): CartItem[] => {
switch (action.type) {
case 'ADD_ITEM':
const existing = state.find(i => i.id === action.payload.id);
if (existing) {
return state.map(i => i.id === action.payload.id ? { ...i, quantity: i.quantity + 1 } : i);
}
return [...state, action.payload];
case 'REMOVE_ITEM':
return state.filter(i => i.id !== action.payload);
case 'CLEAR':
return [];
default:
return state;
}
};
10. Next.js API Route с валидацией
Задача: Создать эндпоинт для регистрации пользователя.
Промт:
Напиши Next.js API route в pages/api/register.ts (или app/api/register/route.ts для App Router). Принимает POST запрос с email и password. Валидируй поля (email формат, password min 6). Если валидация не пройдена — верни 400. В случае успеха — верни 201 и сообщение. Используй Zod для схемы.
Пример результата (App Router):
import { NextResponse } from 'next/server';
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
password: z.string().min(6),
});
export async function POST(request: Request) {
try {
const body = await request.json();
const parsed = schema.parse(body);
// Здесь логика сохранения в БД
return NextResponse.json({ message: 'User created' }, { status: 201 });
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json({ errors: error.errors }, { status: 400 });
}
return NextResponse.json({ message: 'Internal error' }, { status: 500 });
}
}
Категория 3: Экспертные промты (5 шт.)
11. Компонент с Suspense и React.lazy для ленивой загрузки
Задача: Реализовать lazy loading для тяжёлого компонента с fallback.
Промт:
Создай компонент DashboardPage, который импортирует тяжёлый компонент Chart через React.lazy и оборачивает его в Suspense с fallback (скелетон). Используй ErrorBoundary на случай ошибки загрузки чанка. Покажи полный пример с обработкой ошибок.
Пример результата (структура):
import React, { Suspense, lazy } from 'react';
import ErrorBoundary from './ErrorBoundary';
const Chart = lazy(() => import('./Chart'));
const DashboardPage: React.FC = () => {
return (
<ErrorBoundary fallback={<div>Failed to load chart</div>}>
<Suspense fallback={<div className="skeleton" style={{ height: 400 }} />}>
<Chart />
</Suspense>
</ErrorBoundary>
);
};
12. Next.js Middleware для аутентификации
Задача: Написать middleware, который проверяет JWT токен и перенаправляет на логин.
Промт:
Создай Next.js middleware для защиты маршрутов /dashboard и /profile. Middleware должен проверять наличие cookie 'token' и его валидность (имитируй проверку JWT). Если токен отсутствует или недействителен — редирект на /login. Используй NextResponse.rewrite.
Пример результата:
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const protectedPaths = ['/dashboard', '/profile'];
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
const { pathname } = request.nextUrl;
if (protectedPaths.some(p => pathname.startsWith(p))) {
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
// Здесь можно добавить проверку JWT
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*', '/profile/:path*'],
};
13. Оптимизация рендеринга с useTransition и useDeferredValue
Задача: Сделать плавный UI при фильтрации большого списка.
Промт:
Создай компонент SearchableList, который отображает 10000 элементов. Используй useDeferredValue для отложенного обновления списка и useTransition для пометки обновления как низкоприоритетного. Покажи индикатор загрузки во время фильтрации.
Пример результата (ключевая часть):
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
const [isPending, startTransition] = useTransition();
const filtered = useMemo(() => {
return largeList.filter(item => item.name.includes(deferredQuery));
}, [deferredQuery]);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
startTransition(() => setQuery(e.target.value));
};
14. Кастомный хук для работы с localStorage с синхронизацией
Задача: Создать хук, который сохраняет состояние в localStorage и синхронизируется между вкладками.
Промт:
Напиши хук useLocalStorage, который принимает ключ и начальное значение. Хук должен: 1) читать из localStorage при монтировании, 2) обновлять localStorage при изменении, 3) слушать событие storage для синхронизации между вкладками. Используй JSON.parse/stringify.
Пример результата:
function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch {
return initialValue;
}
});
useEffect(() => {
const handleStorage = (e: StorageEvent) => {
if (e.key === key) {
setStoredValue(e.newValue ? JSON.parse(e.newValue) : initialValue);
}
};
window.addEventListener('storage', handleStorage);
return () => window.removeEventListener('storage', handleStorage);
}, [key, initialValue]);
const setValue = (value: T | ((val: T) => T)) => {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
};
return [storedValue, setValue] as const;
}
15. Next.js App Router — параллельные маршруты и интерсепшены
Задача: Создать модальное окно, которое открывается поверх страницы с продуктами.
Промт:
Используя Next.js App Router, настрой параллельный маршрут для модального окна. Страница /products показывает список продуктов. При клике на продукт открывается модальное окно с деталями (роут /products/[id] отображается в модалке). Используй @modal параллельный маршрут и интерсепшн роутов.
Пример результата (структура папок):
app/
page.tsx
layout.tsx
products/
page.tsx
[id]/
page.tsx
@modal/
(.)products/[id]/
page.tsx
default.tsx
Пример layout.tsx:
export default function RootLayout({ children, modal }: { children: React.ReactNode; modal: React.ReactNode }) {
return (
<html>
<body>
{children}
{modal}
</body>
</html>
);
}
Таблица сравнения промтов по сложности и применению
| Категория | Уровень | Пример задачи | Результат | Инструменты |
|---|---|---|---|---|
| Базовые | Junior | Компонент с пропсами | Функциональный компонент | React, TypeScript |
| Базовые | Junior | Форма с валидацией | Рабочая форма | react-hook-form, yup |
| Продвинутые | Middle | SSR страница | Страница с getServerSideProps | Next.js, fetch |
| Продвинутые | Middle | Динамический маршрут | Статические страницы | getStaticPaths |
| Экспертные | Senior | Middleware аутентификации | Защита маршрутов | Next.js Middleware |
| Экспертные | Senior | Параллельные маршруты | Модальное окно | App Router |
Заключение
Правильно составленный промт — это половина успеха при работе с AI-ассистентами. Надеюсь, эта подборка поможет вам быстрее создавать React и Next.js компоненты, избегая типичных ошибок: неполных пропсов, отсутствия типизации или неправильной архитектуры. Помните, что AI — это инструмент, а не замена пониманию. Всегда проверяйте сгенерированный код, тестируйте его и адаптируйте под свой проект.
Если вы хотите углубиться в тему и научиться интегрировать AI в свой рабочий процесс, обратите внимание на курсы, которые обучают практическим навыкам работы с современными фреймворками. ASI Biont поддерживает подключение к различным API для автоматизации разработки — подробнее на asibiont.com/courses.
Пишите в комментариях, какие промты вы используете чаще всего, и делитесь своими находками. Удачного кодинга!
Комментарии