← Назад к вопросам
Можно ли делать запросы к серверу без useEffect?
1.0 Junior🔥 221 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Запросы к серверу без useEffect
Да, можно делать запросы к серверу без useEffect. Есть несколько способов, но нужно понимать, когда и почему их использовать.
1. Обработчик события (onClick, onChange и т.д.)
Самый простой способ — отправить запрос в ответ на действие пользователя:
function LoginForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleLogin = async () => {
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
const data = await response.json();
console.log(data);
};
return (
<div>
<input value={email} onChange={e => setEmail(e.target.value)} />
<input value={password} onChange={e => setPassword(e.target.value)} />
<button onClick={handleLogin}>Войти</button>
</div>
);
}
2. Обработка формы (onSubmit)
function SearchForm() {
const [query, setQuery] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const response = await fetch(`/api/search?q=${query}`);
const results = await response.json();
console.log(results);
};
return (
<form onSubmit={handleSubmit}>
<input value={query} onChange={e => setQuery(e.target.value)} />
<button type="submit">Поиск</button>
</form>
);
}
3. Server Components (Next.js)
В Next.js 13+ Server Components автоматически выполняют запросы на сервере:
// app/page.tsx — это Server Component по умолчанию
async function UserProfile() {
// Запрос выполняется на сервере, браузер никогда не узнает деталей
const response = await fetch('https://api.example.com/user');
const user = await response.json();
return <div>{user.name}</div>;
}
export default UserProfile;
4. Обработчик в API маршруте (Next.js)
// app/api/fetch-data/route.ts
export async function GET(request: Request) {
const response = await fetch('https://api.external.com/data');
const data = await response.json();
return Response.json(data);
}
// В компоненте
async function MyComponent() {
const response = await fetch('/api/fetch-data');
const data = await response.json();
return <div>{JSON.stringify(data)}</div>;
}
5. Кастомный хук (без useEffect)
Хук, который возвращает функцию для запроса:
function useFetch() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const fetch = useCallback(async (url: string) => {
setLoading(true);
try {
const response = await fetch(url);
const result = await response.json();
setData(result);
} finally {
setLoading(false);
}
}, []);
return { data, loading, fetch };
}
// Использование
function MyComponent() {
const { data, loading, fetch } = useFetch();
return (
<>
<button onClick={() => fetch('/api/data')}>Загрузить</button>
{loading && <p>Загрузка...</p>}
{data && <div>{JSON.stringify(data)}</div>}
</>
);
}
6. React Query / TanStack Query
Специальная библиотека для управления состоянием серверных данных:
import { useMutation } from '@tanstack/react-query';
function LoginForm() {
const { mutate: login, isLoading } = useMutation(
(credentials) => fetch('/api/login', {
method: 'POST',
body: JSON.stringify(credentials)
}).then(r => r.json())
);
return (
<button onClick={() => login({ email: 'user@example.com', password: '123' })}>
{isLoading ? 'Загрузка...' : 'Войти'}
</button>
);
}
Когда НЕ использовать useEffect
❌ Избегай useEffect для запросов при инициализации компонента:
// ❌ Плохо — может вызвать двойной запрос в Strict Mode
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('/api/users')
.then(r => r.json())
.then(setUsers);
}, []);
return <div>{users.map(u => u.name).join(', ')}</div>;
}
✅ Используй Server Components вместо этого:
// ✅ Хорошо — запрос на сервере, без лишних запросов
async function UserList() {
const response = await fetch('https://api.example.com/users');
const users = await response.json();
return <div>{users.map(u => u.name).join(', ')}</div>;
}
Сравнение подходов
| Подход | Когда использовать | Плюсы | Минусы |
|---|---|---|---|
| onClick/onChange | Ответ на действие | Просто, предсказуемо | Нужна обработка ошибок |
| useEffect | Инициализация данных | Знаком разработчикам | Может быть лишний запрос |
| Server Components | Статические данные | Безопасно, быстро | Не подходит для интерактива |
| useMutation | Отправка данных | Явное управление | Нужна библиотека |
| React Query | Сложное управление данными | Кэширование, retry | Дополнительная зависимость |
Лучшие практики
✅ Делай запросы:
- В ответ на действие пользователя (click, submit)
- На сервере (Server Components, API routes)
- В специализированных хуках (useMutation, useQuery)
❌ Не делай запросы:
- В теле компонента (вне функций)
- С нарушением Rules of Hooks
- В render-функции
Главное правило: запрос должен быть явным и контролируемым, а не побочным эффектом от рендера компонента.