> Как отобразить одновременно предыдущее и текущее значение пропса в React компоненте? (React)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Сбер
Стек: React
> Пример ответа
Короткий ответ
Для отображения предыдущего и текущего значения пропса в React компоненте используется хук useRef для хранения предыдущего значения и useEffect для его обновления после каждого рендера. Альтернативно можно применить пользовательский хук usePrevious, который инкапсулирует эту логику. Ключевой момент - обновление ref происходит в useEffect, то есть после того, как компонент отрендерился с новым пропсом.
Подробное объяснение
В React нет встроенного механизма для автоматического отслеживания предыдущих значений пропсов, так как компонент получает только текущие пропсы при каждом рендере. Однако, используя useRef, мы можем сохранить значение между рендерами без вызова повторного рендера. Схема работы:
- На каждом рендере текущее значение пропса доступно напрямую.
- В
useEffect(илиuseLayoutEffectдля синхронности) мы обновляем ref, записывая в него текущее значение. - На следующем рендере ref содержит предыдущее значение, которое можно использовать для сравнения или отображения.
Важно понимать, что useEffect выполняется после рендера, поэтому ref всегда отстаёт на один рендер. Это гарантирует, что во время рендера мы видим предыдущее значение в ref и текущее - в пропсе.
На практике
Наиболее распространённый паттерн - создание пользовательского хука usePrevious, который принимает значение и возвращает его предыдущую версию. Этот хук универсален и может использоваться для любых пропсов или state. В компоненте мы просто вызываем const prevValue = usePrevious(value) и используем prevValue и value для отображения.
Если нужно отслеживать изменения нескольких пропсов, можно создать отдельные вызовы usePrevious для каждого. Для сложной логики сравнения (например, глубокое сравнение объектов) потребуется дополнительная обработка в useEffect.
Пример кода
JSXimport { useRef, useEffect } from 'react';// Пользовательский хукfunction usePrevious(value) {const ref = useRef();useEffect(() => {ref.current = value;}, [value]);return ref.current;}// Компонентfunction CounterDisplay({ count }) {const prevCount = usePrevious(count);return (<div><p>Текущее значение: {count}</p><p>Предыдущее значение: {prevCount ?? 'нет предыдущего'}</p></div>);}
Как отвечать на собеседовании
Начни с ключевой идеи: useRef для хранения значения между рендерами и useEffect для его обновления после рендера. Объясни, почему нельзя использовать state (вызовет лишний рендер) или просто переменную (сбросится при ререндере). Упомяни, что хук usePrevious - это канонический паттерн в React, описанный в документации. Если спросят про useLayoutEffect, поясни, что он нужен для синхронного обновления ref до того, как браузер отрисует изменения, но для большинства случаев useEffect достаточно.
Что проверяет интервьюер
Интервьюер оценивает понимание жизненного цикла React компонента, разницы между ref и state, а также умение применять хуки для решения нетривиальных задач. Также проверяется знание того, что useEffect выполняется после рендера, и как это влияет на доступность предыдущего значения. Для senior уровня ожидается объяснение trade-off между useEffect и useLayoutEffect, а также возможные проблемы с замыканиями.
Типичные ошибки
- Использование
useStateдля хранения предыдущего значения - это вызывает лишний рендер и может привести к бесконечному циклу. - Обновление ref непосредственно в теле компонента (без
useEffect) - ref будет содержать текущее значение, а не предыдущее, так как присваивание происходит до рендера. - Забывание обработать случай первого рендера, когда предыдущего значения нет - нужно использовать
undefinedилиnullкак начальное значение ref. - Использование
usePreviousс примитивами без указания зависимости вuseEffect- если не указать[value], хук не будет отслеживать изменения.
> Похожие задачи по frontend
Почему React-компонент может вызываться два раза подряд?
Что такое forwardRef в React и для чего он используется?
Что такое пропсы в React компонентах
Что такое strict mode в React и зачем он нужен
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью