Проблема в том, что ты запускаешь асинхронные действия в useEffect. Это не очень правильно, логику лучше выносить отдельно, а её результаты складывать в стор.
Если нужно очень быстро пофиксить без рефакторинга, то можно добавить проверку на размонтирование, чтобы не менять стейт размонтированного компонента.
const useCheckMounted = (): (() => boolean) => {
const ref = useRef(true)
useLayoutEffect(() => {
ref.current = true
return () => {
ref.current = false
}
}, [ref])
return useCallback(() => {
return ref.current
}, [ref])
}
// пример использования:
const Child: React.FC = React.memo(() => {
const check = useCheckMounted()
useEffect(() => {
console.log('check1, ', check())
setTimeout(() => {
console.log('check2, ', check())
}, 8000)
}, [check])
return <div>child</div>
})
этот компонент запускает setTimeout, символизирующий долгий запрос. Перед запуском check() возвращает true - компонент смонтирован. При ответе сервера check() вернет false, если компонент слетел, или true, если ещё жив.
Пример на TS, если что - просто убери типы