Выбор ответа Senior memo, useMemo, useCallback обновлено

Перерендерится ли children

Вопрос

В ScrollTracker на каждый скролл меняется state y. Перерендерится ли HeavyTree (без memo) при прокрутке?

function ScrollTracker({ children }) {
  const [y, setY] = useState(0);
  useEffect(() => {
    const onScroll = () => setY(window.scrollY);
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return <div><span>{y}</span>{children}</div>;
}

function App() {
  return <ScrollTracker><HeavyTree /></ScrollTracker>;
}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Нет: элемент создан в App, children та же ссылка. Элемент <HeavyTree / создаётся при рендере App, а не ScrollTracker.

Варианты ответа

  1. Да: всё внутри ScrollTracker рендерится при смене его state
  2. Да, но в dev-режиме: в продакшене React пропустит поддерево
  3. Нет, потому что у HeavyTree нет props, сравнивать нечего
  4. Нет: элемент создан в App, children та же ссылкаправильный ответ

Разбор

Элемент <HeavyTree /> создаётся при рендере App, а не ScrollTracker. Пока App не рендерится, children это тот же объект, и React не вызывает HeavyTree повторно. Это приём композиции, который работает без memo. Режим сборки здесь ни на что не влияет. Отсутствие props не спасло бы, если бы элемент создавался внутри ScrollTracker.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме