Поскольку это асиновый вызов обещания c, поэтому вы должны использовать изменчивую переменную ref (с useRef) , чтобы проверить уже отключенный компонент для следующей обработки ответа asyn c (во избежание утечек памяти) ):
Предупреждение. Невозможно выполнить обновление состояния React для неустановленного компонента.
Два элемента React Hook, которые следует использовать в этом случае: useRef
и useEffect
.
Например, при useRef
изменяемая переменная _isMounted
всегда указывает на одну и ту же ссылку в памяти (не локальная переменная)
useRef - это крюк go, если требуется переменная переменная. В отличие от локальных переменных, React гарантирует, что одна и та же ссылка возвращается во время каждого рендеринга. Если хотите, то же самое с this.myVar в компоненте класса
Пример:
const login = (props) => {
const _isMounted = useRef(true); // Initial value _isMounted = true
useEffect(() => {
return () => { // ComponentWillUnmount in Class Component
_isMounted.current = false;
}
}, []);
function handleSubmit(e) {
e.preventDefault();
setLoading(true);
ajaxCall = Inertia.post(window.route('login.attempt'), values)
.then(() => {
if (_isMounted.current) { // Check always mounted component
// continue treatment of AJAX response... ;
}
)
}
}
По тому же случаю позвольте мне объяснить вам больше информации о React Hooks, используемых здесь. Также я буду сравнивать React Hooks в Функциональном Компоненте (версия React> 16.8) с LifeCycle в Компоненте Класса.
useEffect : Большинство побочных эффектов происходят внутри крючка. Примерами побочных эффектов являются: выборка данных, настройка подписки и изменение DOM вручную в компонентах React. UseEffect заменяет множество LifeCycles в компоненте класса (componentDidMount, componentDidUpate, componentWillUnmount)
useEffect(fnc, [dependency1, dependency2, ...]); // dependencies array argument is optional
1) Поведение по умолчанию для useEffect запускается как после первого рендеринга (например, ComponentDidMount) и после каждого обновления визуализируйте (например, ComponentDidUpdate) , если у вас нет зависимостей. Это так: useEffect(fnc);
2) Предоставление массива зависимостей для использованияEffect изменит его жизненный цикл. В этом примере: useEffect будет вызываться один раз после первого рендеринга, и каждый раз при изменении счетчика
export default function () {
const [count, setCount] = useState(0);
useEffect(fnc, [count]);
}
3) useEffect будет запускаться только один раз после первого рендеринга (например, ComponentDidMount) , если вы поставить пустой массив для зависимости. Это так: useEffect(fnc, []);
4) Чтобы предотвратить утечку ресурсов, все должно быть утилизировано, когда жизненный цикл ловушки заканчивается (как ComponentWillUnmount) . Например, с пустым массивом зависимостей, возвращаемая функция будет вызываться после размонтирования компонента. Это так:
useEffect(() => {
return fnc_cleanUp; // fnc_cleanUp will cancel all subscriptions and asynchronous tasks (ex. : clearInterval)
}, []);
useRef : возвращает изменяемый объект ref , свойство .current которого инициализируется переданным аргумент (initialValue). Возвращенный объект будет сохраняться в течение всего времени жизни компонента.
Пример: с вопросом выше, мы не можем использовать локальную переменную здесь, потому что она будет потеряна и повторно инициируется при каждом обновлении render.
const login = (props) => {
let _isMounted= true; // it isn't good because of a local variable, so the variable will be lost and re-initiated on every update render
useEffect(() => {
return () => {
_isMounted = false; // not good
}
}, []);
// ...
}
Итак, с комбинацией useRef и useEffect мы могли бы полностью устранить утечки памяти.
Хорошо ссылки, которые вы можете прочитать больше о React Hooks:
[EN] https://medium.com/@sdolidze / the-iceberg-of-response-hooks-af0b588f43fb
[FR ] https://blog.soat.fr/2019/11/react-hooks-par-lexemple/