> Как реализовать кастомный хук для отслеживания первого рендера в React? (React, JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Альфа-банк
Стек: React, JavaScript
> Пример ответа
Короткий ответ
Кастомный хук useIsFirstRender можно реализовать через useRef: создаём ref с true, в useEffect (или useLayoutEffect) меняем на false. Возвращаем ref.current. Это позволяет отличить первый рендер от последующих без лишних ререндеров. Альтернативно - использовать useMemo с флагом, но ref надёжнее, так как не вызывает повторных вычислений.
Подробное объяснение
Основная задача - определить, выполняется ли рендер компонента впервые. React не предоставляет встроенного API для этого, поэтому используем useRef, который сохраняет значение между рендерами без вызова ререндера.
Ключевой момент: useEffect выполняется после того, как React зафиксировал изменения в DOM. Если установить флаг в useEffect, то во время первого рендера ref.current всё ещё будет true, а начиная со второго - false.
useLayoutEffect срабатывает синхронно после всех мутаций DOM, но до того, как браузер отрисует изменения. Разница с useEffect минимальна для этой задачи, но useLayoutEffect может быть предпочтительнее, если нужно избежать визуального мерцания при первом рендере.
Важно: хук не должен вызывать ререндер - поэтому используем useRef, а не useState.
На практике
Хук полезен для:
- Отключения анимаций при первом рендере (чтобы избежать "вспышки").
- Условного выполнения эффектов (например, не логировать первый рендер).
- Реализации паттерна "componentDidMount" в функциональных компонентах.
- Сравнения предыдущих и текущих пропсов (в комбинации с
usePrevious).
Стоит учитывать, что в React 18 Strict Mode useEffect вызывается дважды в development - это может повлиять на логику, если хук используется внутри эффекта. В production такого нет.
Пример кода
JAVASCRIPTimport { useRef, useEffect } from 'react';function useIsFirstRender() {const isFirst = useRef(true);useEffect(() => {isFirst.current = false;}, []);return isFirst.current;}// Использованиеfunction MyComponent() {const isFirstRender = useIsFirstRender();useEffect(() => {if (isFirstRender) {console.log('Первый рендер');} else {console.log('Последующий рендер');}}, [isFirstRender]);return <div>Content</div>;}
Как отвечать на собеседовании
Начни с краткого объяснения задачи - отличить первый рендер от последующих. Упомяни, что используешь useRef из-за его стабильности и отсутствия ререндеров. Объясни, почему useEffect подходит для установки флага: он выполняется после фиксации в DOM.
Если спросят про альтернативы, скажи, что можно использовать useMemo с пустыми зависимостями, но это менее надёжно, так как useMemo может быть пересчитан React при оптимизациях. Также упомяни useLayoutEffect как альтернативу для синхронного обновления.
Подчеркни, что хук не вызывает лишних ререндеров - это его главное преимущество. Если собеседник спросит про Strict Mode, объясни поведение в development.
Что проверяет интервьюер
- Понимание разницы между
useRef,useState,useEffectиuseLayoutEffect. - Знание жизненного цикла функциональных компонентов.
- Умение избегать лишних ререндеров.
- Понимание, когда и зачем нужен такой хук.
- Способность объяснить trade-off между
useEffectиuseLayoutEffect.
Типичные ошибки
- Использование
useStateвместоuseRef- это вызывает лишний ререндер при первом вызове. - Установка флага внутри рендера (не в эффекте) - тогда флаг всегда будет
true, так как код выполняется до завершения рендера. - Забывание про Strict Mode - в development эффект может выполниться дважды, что сбросит флаг.
- Возврат
isFirst.currentнапрямую из хука без учёта времени выполнения - если компонент ререндерится до вызова эффекта, значение может быть некорректным.
> Похожие задачи по frontend
Как обработать ошибки в React приложении
Как реализовать добавление и удаление кнопок с уникальными id в React при кликах
Для чего нужен React.lazy
На чем реализован сайт для велосипедов, используется ли React
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью