React axios 请求要求 UseEffect 清理函数取消所有订阅和异步任务



我正在使用 axios 从我的 API 获取一些数据,但所有请求都不在 useEffect 函数中。甚至更多 - 我完全没有使用useEffect。

以下是我的代码的一部分:

JSX:

<form onSubmit={onSubmitLogin}>
<div className="form sign-in">
<h2>Hello again,</h2>
<div className="div-label">
<label>
<span>Email</span>
<input type="email" onChange={onLoginEmailChange} />
</label>
</div>
<div className="div-label">
<label>
<span>Password</span>
<input type="password" onChange={onLoginPasswordChange} />
</label>
</div>
<p className="forgot-pass">Forgot password?</p>
{loading && (
<img
alt="svg"
className="loading-img"
align="middle"
width={35}
height={35}
src={mySvg}
/>
)}
{!loading && (
<input className="submit" type="submit" value="Sign In" />
)}

所以这是在调用:

const onSubmitLogin = e => {
e.preventDefault();
setLoading(true);
axios
.get(
`http://myapiURL/?email=${loginEmail}&password=${loginPassword}`
)
.then(res => {
console.log(res);
if (res.status === 200) {
console.log("here");
history.push({
pathname: "/dashboard",
state: res.data
});
setLoading(false);
}
})
.catch(e => {
console.log(e);
});
};

这是有效的,它给了我数据,但在浏览器中我看到这个错误:

index.js:1375 警告:无法对未挂载的组件执行 React 状态更新。这是无操作,但它表示应用程序中存在内存泄漏。若要解决此问题,请取消 useEffect 清理函数中的所有订阅和异步任务。 在登录中(由Context.Consumer创建(

我发现了很多关于这个的信息,但所有这些都与他们把他们的请求方法放在useEffect中有关。
PS:顺便说一下,我正在使用 React 钩子(使用状态,但不是这个组件中的 useEffect(

在 onSubmitLogin 上,您正在推送到另一个路径名,这会引发组件卸载,然后,您正在尝试从已经卸载的组件更新状态(在 history.push 之后拥有的 setLoad(false(。

您可以在历史记录推送之前设置加载(false(,也可以从那里删除 setLoading 并创建一个 useEffect 以在该清理周期中将加载状态设置为 false。 如:

useEffect(() => {
return () => {
setLoading(false);
}
}, [])

useEffect 的返回将在更改为另一个组件(如 ComponentWillUnmount 生命周期(之前执行。

您正在为未挂载的组件设置状态,因此您必须在history.push之前调用setLoading

const onSubmitLogin = e => {
e.preventDefault();
setLoading(true);
axios
.get(
`http://myapiURL/?email=${loginEmail}&password=${loginPassword}`
)
.then(res => {
console.log(res);
if (res.status === 200) {
console.log("here");
setLoading(false);
history.push({
pathname: "/dashboard",
state: res.data
});
}
})
.catch(e => {
console.log(e);
});
};

如果在异步函数完成之前卸载组件并尝试设置某些状态 var,则可能会出现此问题

要解决此问题,您可以执行以下操作:

React.useEffect(() => {
let isSubscribed = true;
axios
.get(
`http://myapiURL/?email=${loginEmail}&password=${loginPassword}`
)
.then(res => {
console.log(res);
if (res.status === 200) {
history.push({
pathname: "/dashboard",
state: res.data
});
// check if this component still mounted
if (isSubscribed) {
setLoading(false);
}
}
});
return () => (isSubscribed = false);
}, []);

最新更新