У мене є компонент:
function Counter() {
const [count, setCount] = useState(0);
console.log("render");
return <button onClick={() => setCount(0)}>Reset</button>;
}
Коли я натискаю кнопку Reset, у консолі знову бачу "render" — навіть якщо count вже був 0. Це нормально? Як цього уникнути?
Питання закрите для нових відповідей.
Експерт обрав найкращою
1 Відповідь
Так, це нормальна поведінка React. Коли ви викликаєте setCount(0), React не порівнює «глибоко» нове значення з попереднім. Він просто планує перерендер.
Чому так
React використовує Object.is() для порівняння стейту. Для примітивів (числа, рядки) це працює — той самий 0 === 0 не викликає перерендер. Але важливий нюанс:
- React може зробити перший «virtual» рендер для підрахунку
- Якщо результат той самий — DOM не оновлюється
- Але
console.logу тілі компонента все одно спрацьовує
Як уникнути зайвих обчислень
Використовуйте React.memo для дочірніх компонентів і useMemo / useCallback для важких обчислень:
const ExpensiveChild = React.memo(({ value }) => {
// не перерендериться якщо value не змінилось
return <div>{value}</div>;
});
Для дебагу зайвих рендерів — встановіть React DevTools і ввімкніть «Highlight updates».
Експерт обрав найкращою