Выбор ответа Senior Паттерны компонентов обновлено
children и перерисовка
Вопрос
При движении мыши Tracker меняет состояние. Перерисуется ли ExpensiveTree?
function Tracker({ children }) {
const [pos, setPos] = useState({ x: 0, y: 0 });
return (
<div onPointerMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>
<p>{pos.x}, {pos.y}</p>
{children}
</div>
);
}
function App() {
return (
<Tracker>
<ExpensiveTree />
</Tracker>
);
}
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Нет: элемент создан в App и пришёл в children той же ссылкой. Элемент <ExpensiveTree / создаётся при рендере App, а App не перерисовывается.
Варианты ответа
- Да, при каждом движении: родитель перерисовался
- Нет: элемент создан в
Appи пришёл вchildrenтой же ссылкойправильный ответ - Да, если только
ExpensiveTreeне обёрнут вmemo - Нет: React не перерисовывает компоненты внутри обработчиков событий
Разбор
Элемент <ExpensiveTree /> создаётся при рендере App, а App не перерисовывается. В Tracker приходит тот же объект элемента, и React видит, что он не изменился, поэтому ExpensiveTree не рендерится. Это приём «опустить состояние вниз и передать тяжёлое через children», он работает без memo.
- Перерисовался
Tracker, но не тот, кто создал элемент. memoтут не нужен.- Обработчики событий не влияют на правило.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.