Повышение производительности React‑компонентов

Оберните Child в React.memo и стабилизируйте onInputChange через useCallback. Тогда обновление text не меняет props дочернего компонента.

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

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

Оберните Child в React.memo и стабилизируйте onInputChange через useCallback. Тогда обновление text не меняет props дочернего компонента.

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

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

Условие

Требуется улучшить представленный React‑пример так, чтобы компонент Child не перерисовывался при вводе текста в поле ввода.

import React from 'react';

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

const Parent = () => {
  const [text, setText] = React.useState('');
  const onInputChange = (e) => {
    setText(e.target.value);
  };
  return (
    <form style={{ margin: '20px', padding: '20px', border: '2px solid blue' }}>
      Input value is: {text}
      <RenderCount />
      <Child onChange={onInputChange} />
    </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>
  );
}

Задача — применить подходящие техники (например, React.memo, useCallback и т.п.), чтобы дочерний компонент оставался неизменным при каждом изменении состояния ввода в родителе.

Ответ

Оберните Child в React.memo и стабилизируйте onInputChange через useCallback. Тогда обновление text не меняет props дочернего компонента.

// В Parent:
const onInputChange = React.useCallback(e => setText(e.target.value), []);

const Child = React.memo(({ onChange }) => <div>
  <input type='text' name='value' onChange={onChange} />
  <RenderCount />
</div>);

Здесь input остаётся uncontrolled и отображает ввод средствами DOM. Memo — оптимизация, не абсолютная гарантия числа вызовов; собственное состояние и context могут обновить Child. Реализация useForceUpdate в исходнике не приведена.

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

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

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

Подробнее