我正在使用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有关。
P.S .:顺便说一下,我正在使用React钩子(在此组件中使用useState而不是useEffect)
答案 0 :(得分:0)
在onSubmitLogin上,您将推到另一个路径名,该路径名将导致要卸载的组件,然后,您尝试从已卸载的组件(在历史记录之后具有setLoading(false)的状态)更新状态。 )。
您可以在历史记录推送之前设置setLoading(false)或从此处删除setLoading并创建useEffect,以在该清理周期中将加载状态设置为false。喜欢:
useEffect(() => {
return () => {
setLoading(false);
}
}, [])
useEffect的返回将在更改为另一个组件(例如ComponentWillUnmount生命周期)之前执行。
答案 1 :(得分:0)
您正在为未安装的组件设置状态,因此必须在setLoading
之前调用history.push
:
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);
});
};
答案 2 :(得分:0)
如果在异步函数完成之前卸载组件并尝试设置一些状态变量,可能会出现此问题
要解决此问题,您可以执行以下操作:
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);
}, []);