Сохраняйте последний committed count в ref, а cleanup эффекта с [] пусть читает этот ref. Зависимость [count] у cleanup вызвала бы отправку при каждом изменении счётчика.
Передача текущего счётчика в аналитику при размонтировании компонента
Сохраняйте последний committed count в ref, а cleanup эффекта с [] пусть читает этот ref. Зависимость [count] у cleanup вызвала бы отправку при каждом изменении счётчика.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо реализовать отправку текущего значения счётчика в систему аналитики в момент, когда компонент будет удалён из DOM. При этом следует обеспечить: ‑ сохранение актуального значения счётчика в момент unmount; ‑ отсутствие лишних вызовов отправки при каждом ререндере или клике.
function Component(props) {
const [count, setCount] = useState(0);
const onIncrement = () => {
setCount(s => s + 1);
};
useEffect(() => {
// отправка count при unmount
return () => {
// analyticsService.send(count)
};
}, []);
if (count % 2 === 0) {
return <MyButton handleClick={onIncrement} />;
}
return (
<>
<div>{count}</div>
<MyButton handleClick={onIncrement} />
</>
);
}
Ответ
Сохраняйте последний committed count в ref, а cleanup эффекта с [] пусть читает этот ref. Зависимость [count] у cleanup вызвала бы отправку при каждом изменении счётчика.
const latest = useRef(count);
useLayoutEffect(() => { latest.current = count; }, [count]);
useEffect(() => {
return () => analyticsService.send(latest.current);
}, []);
Нужны импорты useRef/useLayoutEffect. Ref обновляется после commit, не во время потенциально отменённого рендера. В development Strict Mode cleanup запускается также проверочно, поэтому это не гарантия «ровно одна отправка за жизнь»; аналитике нужна дедупликация или явное продуктовое событие. Закрытие вкладки вообще не гарантирует React-unmount: для надёжной доставки требуется отдельная политика page lifecycle/sendBeacon, а не только cleanup.