Когда нужно быстро набросать компонент или страницу на React и Next.js, правильный промт экономит часы. В этой подборке — 12 проверенных запросов, которые я сам использую в ежедневной фронтенд-разработке. Каждый сопровождается примером кода и пояснением, почему он работает.
1. Функциональный компонент с TypeScript
Промт: «Напиши React-компонент на TypeScript, который принимает пропсы title: string и items: string[], и рендерит список с заголовком. Добавь типизацию пропсов через интерфейс.»
Пример:
interface ListProps {
title: string;
items: string[];
}
const List: React.FC<ListProps> = ({ title, items }) => (
<div>
<h2>{title}</h2>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
export default List;
Почему работает: Запрос явно указывает типы и структуру, AI не гадает — результат сразу готов к вставке.
2. Компонент с хуками useState и useEffect
Промт: «Создай компонент Timer, который показывает секунды, запускает таймер при монтировании и очищает при размонтировании. Используй useState и useEffect, типизируй состояние как number.»
Пример:
import { useState, useEffect } from 'react';
const Timer: React.FC = () => {
const [seconds, setSeconds] = useState<number>(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <div>Прошло: {seconds} сек</div>;
};
Почему работает: Упомянуты жизненный цикл и очистка — AI корректно добавляет return в эффект.
3. Серверный компонент в Next.js App Router
Промт: «Напиши серверный компонент для Next.js App Router, который получает список пользователей из JSONPlaceholder (https://jsonplaceholder.typicode.com/users) и рендерит карточки с именем и email. Компонент должен быть асинхронным и выполняться на сервере.»
Пример:
// app/users/page.tsx
interface User {
id: number;
name: string;
email: string;
}
async function UsersPage() {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
const users: User[] = await res.json();
return (
<div>
{users.map((user) => (
<div key={user.id}>
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
))}
</div>
);
}
export default UsersPage;
Почему работает: Явное указание на серверный рендеринг и источник данных — AI генерирует async-компонент без лишних клиентских хуков.
4. Клиентский компонент с 'use client'
Промт: «Создай клиентский компонент в Next.js App Router, который использует useState для переключения темы (светлая/тёмная). Добавь директиву 'use client' в начале файла.»
Пример:
'use client';
import { useState } from 'react';
const ThemeToggle: React.FC = () => {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Текущая тема: {theme}
</button>
);
};
5. Страница Pages Router с getStaticProps
Промт: «Напиши страницу Next.js (Pages Router), которая получает список постов через getStaticProps из JSONPlaceholder и передаёт их в компонент. Добавь типизацию пропсов.»
Пример:
import { GetStaticProps } from 'next';
interface Post {
id: number;
title: string;
}
interface Props {
posts: Post[];
}
const Posts: React.FC<Props> = ({ posts }) => (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
export const getStaticProps: GetStaticProps = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/posts');
const posts: Post[] = await res.json();
return { props: { posts } };
};
export default Posts;
6. Кастомный хук для работы с API
Промт: «Создай кастомный хук useFetch
Пример:
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((data: T) => setData(data))
.catch((err) => {
if (err.name !== 'AbortError') setError(err.message);
})
.finally(() => setLoading(false));
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
7. Компонент с Context API
Промт: «Создай контекст авторизации AuthContext с состоянием { user, login, logout }. Реализуй провайдер и хук useAuth. Типизируй контекст.»
Пример (упрощённо):
import { createContext, useContext, useState, ReactNode } from 'react';
interface AuthContextType {
user: string | null;
login: (name: string) => void;
logout: () => void;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [user, setUser] = useState<string | null>(null);
const login = (name: string) => setUser(name);
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) throw new Error('useAuth must be used within AuthProvider');
return context;
};
8. Форма с валидацией (React Hook Form)
Промт: «Создай форму регистрации с полями: email (обязательно, формат email), password (минимум 6 символов). Используй react-hook-form и yup для валидации. Выводи ошибки под каждым полем.»
Пример:
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';
const schema = yup.object({
email: yup.string().email().required(),
password: yup.string().min(6).required(),
});
type FormData = yup.InferType<typeof schema>;
const RegistrationForm: React.FC = () => {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: yupResolver(schema),
});
const onSubmit = (data: FormData) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email')} placeholder='Email' />
<p>{errors.email?.message}</p>
<input type='password' {...register('password')} placeholder='Пароль' />
<p>{errors.password?.message}</p>
<button type='submit'>Зарегистрироваться</button>
</form>
);
};
9. Анимация с Framer Motion
Промт: «Напиши компонент, который анимирует появление блока сдвигом слева с opacity при монтировании. Используй framer-motion, вариант 'hidden' и 'visible'.»
Пример:
import { motion } from 'framer-motion';
const AnimatedBlock: React.FC = () => (
<motion.div
initial={{ opacity: 0, x: -100 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.5 }}
>
Привет, анимация!
</motion.div>
);
10. Таблица с сортировкой
Промт: «Создай таблицу с колонками Name и Age. Данные — массив объектов { name: string; age: number }. Добавь возможность сортировки по возрасту по клику на заголовок. Используй useState.»
Пример (упрощённо):
import { useState } from 'react';
interface Person { name: string; age: number }
type SortDirection = 'asc' | 'desc';
const Table: React.FC<{ data: Person[] }> = ({ data }) => {
const [sortDir, setSortDir] = useState<SortDirection>('asc');
const sorted = [...data].sort((a, b) =>
sortDir === 'asc' ? a.age - b.age : b.age - a.age
);
return (
<table>
<thead>
<tr>
<th>Name</th>
<th onClick={() => setSortDir(sortDir === 'asc' ? 'desc' : 'asc')}>
Age {sortDir === 'asc' ? '↑' : '↓'}
</th>
</tr>
</thead>
<tbody>
{sorted.map((p, i) => (
<tr key={i}><td>{p.name}</td><td>{p.age}</td></tr>
))}
</tbody>
</table>
);
};
11. Модальное окно с порталом
Промт: «Напиши компонент Modal, который рендерится через React Portal в body. Принимает isOpen, onClose и children. Добавь обработку клика по затемнённому фону для закрытия.»
Пример:
import { useEffect } from 'react';
import { createPortal } from 'react-dom';
interface ModalProps {
isOpen: boolean;
onClose: () => void;
children: React.ReactNode;
}
const Modal: React.FC<ModalProps> = ({ isOpen, onClose, children }) => {
useEffect(() => {
const handleEsc = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
};
window.addEventListener('keydown', handleEsc);
return () => window.removeEventListener('keydown', handleEsc);
}, [onClose]);
if (!isOpen) return null;
return createPortal(
<div
style={{
position: 'fixed', inset: 0, display: 'flex',
alignItems: 'center', justifyContent: 'center',
backgroundColor: 'rgba(0,0,0,0.5)'
}}
onClick={onClose}
>
<div onClick={(e) => e.stopPropagation()}>
{children}
</div>
</div>,
document.body
);
};
12. Компонент с lazy loading и Suspense
Промт: «Создай страницу, которая лениво загружает тяжёлый компонент через React.lazy и оборачивает его в Suspense с fallback (спиннер). Используй React 18+ и Next.js App Router.»
Пример:
import { lazy, Suspense } from 'react';
const HeavyComponent = lazy(() => import('./HeavyComponent'));
const LazyPage: React.FC = () => (
<Suspense fallback={<div>Загрузка...</div>}>
<HeavyComponent />
</Suspense>
);
Эти 12 промтов покрывают 80% типовых задач фронтендера. Сохраните их в шпаргалку — и AI станет вашим ассистентом, а не просто игрушкой. Пробуйте, адаптируйте под свои проекты и пишите более сложные сценарии, комбинируя несколько промтов в одном.
Комментарии