Определение компонентов, переотрисовывающихся при нажатии кнопки в React

Если useForceUpdate действительно обновляет состояние App, без мемоизации перерендерятся App, Parent, Child и все три RenderCount. Повторный рендер не означает замену всех DOM-узлов.

Короткий ответ

Что ответить на собеседовании

Если useForceUpdate действительно обновляет состояние App, без мемоизации перерендерятся App, Parent, Child и все три RenderCount. Повторный рендер не означает замену всех DOM-узлов.

Подробный разбор

Ответ с пояснениями

Условие

Нужно выяснить, какие части интерфейса будут повторно отрисованы после клика по кнопке Render и объяснить причины такой перерисовки.

import React from 'react';

export default function App() {
  const forceUpdate = useForceUpdate();
  return (
    <div style={{ margin: '20px', padding: '20px', border: '2px solid green' }}>
      <button onClick={forceUpdate}>Render</button>
      <RenderCount />
      <Parent />
    </div>
  );
}

const Parent = () => {
  const [value, setValue] = React.useState('');
  const handleChange = (e) => {
    setValue(e.target.value);
  };
  return (
    <form style={{ margin: '20px', padding: '20px', border: '2px solid blue' }}>
      Input value is: {value}
      <RenderCount />
      <Child onChange={handleChange} />
    </form>
  );
};

const Child = ({ onChange }) => {
  return (
    <div style={{ padding: '20px', margin: '20px', border: '2px solid red' }}>
      <input type="text" name="value" onChange={onChange} />
      <RenderCount />
    </div>
  );
};

function RenderCount() {
  const renderCount = React.useRef(1);
  React.useEffect(() => {
    renderCount.current += 1;
  });
  return (
    <div style={{ marginTop: '10px' }}>
      Render count: {renderCount.current}
    </div>
  );
}

Вопросы для анализа:

  • Какие компоненты получат новый рендер после вызова forceUpdate?
  • Почему Parent и Child могут/не могут перерисоваться при этом?
  • Как работает хук RenderCount и как он отражает количество рендеров?
  • Какие оптимизации (например, React.memo) могли бы изменить поведение?

Ответ

Если useForceUpdate действительно обновляет состояние App, без мемоизации перерендерятся App, Parent, Child и все три RenderCount. Повторный рендер не означает замену всех DOM-узлов.

Реализация useForceUpdate не дана: вывод предполагает обычный хук с обновлением собственного состояния. App заново создаёт элементы дочерних компонентов, а Parent создаёт новую handleChange. memo(Parent) со стабильными props может остановить эту ветку; для memo(Child) понадобится стабильная ссылка onChange. RenderCount увеличивает ref в эффекте после commit, не вызывая новый рендер: число становится видимым лишь при следующем рендере. Это не точный профилировщик, особенно в Strict Mode и при отменённых рендерах.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее