> Почему React-компонент может вызываться два раза подряд? (React)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: КИТМЕД
Стек: React
> Пример ответа
Короткий ответ
Двойной вызов React-компонента - это ожидаемое поведение в React 18+ в режиме strict mode. React намеренно вызывает функцию компонента дважды в development-сборке, чтобы обнаружить побочные эффекты, которые могут привести к багам. В production-сборке компонент вызывается один раз.
Подробное объяснение
Начиная с React 18, в strict mode компоненты вызываются дважды в development-окружении. Это не баг, а фича для выявления проблем с чистотой рендеринга. React монтирует компонент, размонтирует его и монтирует снова, вызывая функцию компонента дважды подряд. Это помогает обнаружить:
- Побочные эффекты в теле компонента (например, мутации внешних переменных)
- Неправильное использование хуков (useEffect, useMemo, useCallback)
- Проблемы с инициализацией состояния
- Утечки памяти из-за неправильной очистки эффектов
React проверяет, что компонент ведёт себя как чистая функция: при одинаковых props и state возвращает одинаковый JSX. Если при повторном вызове результат отличается, это сигнал о проблеме.
На практике
Для senior-разработчика важно понимать, что двойной вызов - это инструмент отладки, а не runtime-баг. При работе с:
- useEffect: проверяется, что cleanup-функция корректно отрабатывает
- useMemo/useCallback: проверяется, что вычисления не имеют побочных эффектов
- инициализация состояния: проверяется, что начальное состояние не зависит от внешних мутаций
В production-сборке (NODE_ENV=production) двойного вызова не происходит. Если вы видите двойной вызов в production - это отдельная проблема, связанная с архитектурой приложения (например, лишние ререндеры из-за неправильных зависимостей).
Пример кода
JSXfunction Counter() {console.log('Component called'); // будет дважды в development strict modeconst [count, setCount] = useState(() => {console.log('Initializer called'); // тоже дваждыreturn 0;});useEffect(() => {console.log('Effect runs'); // один разreturn () => console.log('Cleanup'); // один раз}, []);return <div>{count}</div>;}
Как отвечать на собеседовании
Начни с того, что это intentional behavior в React 18+ strict mode для development. Объясни, что React проверяет чистоту компонента. Упомяни, что в production этого нет. Покажи понимание, как это влияет на useEffect, useMemo и инициализацию state. Добавь, что это помогает ловить баги на раннем этапе, особенно с асинхронными операциями и подписками.
Что проверяет интервьюер
- Понимание разницы между development и production сборками
- Знание strict mode и его целей
- Умение отличать intentional behavior от багов
- Понимание концепции чистых компонентов
- Опыт работы с побочными эффектами в React
Типичные ошибки
- Считать двойной вызов багом React
- Пытаться "исправить" это через обёртки или мемоизацию
- Не знать, что в production этого не происходит
- Путать двойной вызов компонента с двойным вызовом эффекта (useEffect выполняется один раз)
- Думать, что это связано с Concurrent Mode или Suspense
> Похожие задачи по frontend
Как передать данные с одного микрофронтенда на другой в React?
Как оптимизировать React компонент, чтобы Child компонент не перерендеривался при вводе текста?
Что такое forwardRef в React и для чего он используется?
Как отобразить одновременно предыдущее и текущее значение пропса в React компоненте?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью