Мемоизация полезна для чистого дорогого вычисления, но Date.now меняется со временем: кэширование изменит наблюдаемое поведение. handleSend зависит от inputText и не может быть навсегда заморожен через [].
Повышение эффективности рендеринга React‑компонентов
Мемоизация полезна для чистого дорогого вычисления, но Date.now меняется со временем: кэширование изменит наблюдаемое поведение. handleSend зависит от inputText и не может быть навсегда заморожен через [].
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В этом примере реализовано небольшое React‑приложение, где при каждом рендере вызывается дорогая функция и несколько дочерних компонентов перерисовываются без необходимости. Задача — предложить оптимизации, позволяющие избежать лишних вычислений и ререндеров, используя такие инструменты, как React.memo, useCallback, useMemo и другие подходы к управлению зависимостями.
import React from "react";
import { useState } from "react";
export const App = () => {
const [baseNumber] = useState(9);
const [inputText, setInputText] = useState("");
const computeHeavy = () => {
console.log("computeHeavy");
return baseNumber + Date.now();
};
const handleSend = () => {
console.log("send text = ", inputText);
};
return (
<div>
<TextField text={inputText} setText={setInputText} />
<HeavySendButton onClick={handleSend} />
<pre>{computeHeavy()}</pre>
<button onClick={handleSend}>Кнопка отправки 2</button>
</div>
);
};
const HeavySendButton = ({ onClick }) => {
console.log("SendButton render");
return <button onClick={onClick}>Кнопка отправки 1</button>;
};
const TextField = ({ text, setText }) => {
return (
<input value={text} onChange={(event) => setText(event.target.value)} />
);
};
Ответ
Мемоизация полезна для чистого дорогого вычисления, но Date.now меняется со временем: кэширование изменит наблюдаемое поведение. handleSend зависит от inputText и не может быть навсегда заморожен через [].
Сначала определите, что означает время в результате. Если это время создания компонента, сохраните его в state/ref; если текущие часы — обновляйте их отдельным механизмом. Для чистой функции от baseNumber используйте useMemo с зависимостью baseNumber.
HeavySendButton можно обернуть в React.memo, а handleSend — в useCallback с [inputText]. Это пропустит только рендеры, где текст не менялся: при вводе callback закономерно новый. TextField должен обновляться при изменении text. Оптимизацию начинайте с измерения реальной дороговизны; простой baseNumber + Date.now() сам по себе тяжёлой операцией не является.