← Назад к вопросам

Можно ли делать запросы к серверу без 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-функции

Главное правило: запрос должен быть явным и контролируемым, а не побочным эффектом от рендера компонента.

Можно ли делать запросы к серверу без useEffect? | PrepBro