Оптимизация и улучшение React‑компонента

Все хуки должны вызываться до условного return и вне if. Условия перенесите внутрь эффекта, добавьте зависимости gameId/platform, обработку ошибки и защиту от устаревшего ответа.

Короткий ответ

Что ответить на собеседовании

Все хуки должны вызываться до условного return и вне if. Условия перенесите внутрь эффекта, добавьте зависимости gameId/platform, обработку ошибки и защиту от устаревшего ответа.

Подробный разбор

Ответ с пояснениями

Условие

Дан React‑компонент Game. Требуется провести рефакторинг, исправив неправильное использование хуков и улучшив читаемость кода.

export const Game = ({ gameId }) => {
  const currentPlatform = useSelector(selectSiteVersion); // 'mobile' | 'desktop'

  const [loading, setLoading] = useState(false);
  const [fullScreen, setFullScreen] = useState(false);
  const [gameInfo, setGameInfo] = useState({ title: '', description: '' });

  if (!gameId) {
    return <div>Empty</div>;
  }

  const requestParams = {
    id: gameId,
    mode: 'real',
    platform: currentPlatform,
  };

  const fetchGame = async () => {
    setLoading(true);
    const game = await requestGame(requestParams);
    setLoading(false);
    setGameInfo(game);
  };

  if (currentPlatform === 'mobile') {
    useEffect(() => {
      fetchGame();
    }, []);
  }

  useEffect(() => {
    const handler = () => setFullScreen(prev => !prev);
    document.addEventListener('fullscreenchange', handler);
    return () => document.removeEventListener('fullscreenchange', handler);
  }, []);

  return (
    <div>
      <div>{gameInfo.title}</div>
      <div>{gameInfo.description}</div>
      {loading && <div>Loading...</div>}
    </div>
  );
};

Ответ

Все хуки должны вызываться до условного return и вне if. Условия перенесите внутрь эффекта, добавьте зависимости gameId/platform, обработку ошибки и защиту от устаревшего ответа.

После useState добавьте error и замените эффекты; ранний return перенесите ниже них.

const [error, setError] = useState('');
useEffect(() => {
  let active = true;
  setGameInfo({ title: '', description: '' });
  setError('');
  if (!gameId || currentPlatform !== 'mobile') {
    setLoading(false);
    return;
  }
  setLoading(true);
  (async () => {
    try {
      const game = await requestGame({ id: gameId, mode: 'real', platform: currentPlatform });
      if (active) setGameInfo(game);
    } catch {
      if (active) setError('Не удалось загрузить игру');
    } finally {
      if (active) setLoading(false);
    }
  })();
  return () => { active = false; };
}, [gameId, currentPlatform]);
useEffect(() => {
  const handler = () => setFullScreen(Boolean(document.fullscreenElement));
  handler();
  document.addEventListener('fullscreenchange', handler);
  return () => document.removeEventListener('fullscreenchange', handler);
}, []);

Покажите error в JSX и используйте fullScreen для интерфейса либо удалите ненужное состояние. Здесь сохранено исходное правило загрузки только на mobile; если игра нужна и на desktop, уберите это условие явно. Отмена сетевого запроса требует поддержки signal в requestGame; active лишь предотвращает позднюю запись состояния.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее