Оберните Child в React.memo и стабилизируйте onInputChange через useCallback. Тогда обновление text не меняет props дочернего компонента.
Повышение производительности React‑компонентов
Оберните 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 в исходнике не приведена.