在制作一个项目的过程中,我遇到了React钩子的问题。
我使用useEffect来渲染UI到用户分类,我使用let history = useHistory()来做到这一点,在代码部分:
if (isAuthenticated() && isAuthenticated().role === 1) {
//! Redirect to Admin dashboard
console.log('Redirect to Admin dashboard');
history.push('/admin/dashboard'); //! I found that using this code will cause a warning
} else {
//! Redirect to User dashboard
console.log('Redirect to User dashboard');
history.push('/user/dashboard'); //! I found that using this code will cause a warning
}
历史。生成警告。警告:无法在未挂载的组件上执行React状态更新。这是一个无操作,但它表明应用程序中存在内存泄漏。在useEffect清理函数中取消所有订阅和异步任务。
my full Code:
const Signin = () => {
let history = useHistory();
//! Check Authenticated after Component does Mount
useEffect(() => {
if (isAuthenticated() && isAuthenticated().role === 1) {
//! Redirect to Admin dashboard
history.push('/admin/dashboard');
} else if (isAuthenticated() && isAuthenticated().role === 0) {
//! Redirect to User dashboard
history.push('/user/dashboard');
}
}, [history]);
const [formData, setFormData] = useState({
username: "",
email: "",
password: "",
errorMsg: false,
loading: false
});
const { username, email, password, errorMsg, loading } = formData;
const handleSubmit = (e) => {
e.preventDefault();
//! client validation
if (isEmpty(email) || isEmpty(password)) {
setFormData({...formData, errorMsg: "Enter your information"});
} else if (!isEmail(email)) {
setFormData({...formData, errorMsg: "Email invalid"});
} else {
setFormData({...formData, loading: true});
// Send data to server
const data = { user : { email, password } };
signin(data) //! return response
.then(response => {
setAuthentication(response.data.token, response.data.user);
if (isAuthenticated() && isAuthenticated().role === 1) {
//! Redirect to Admin dashboard
history.push('/admin/dashboard');
} else {
//! Redirect to User dashboard
history.push('/user/dashboard');
}
setFormData({
...formData,
loading: false,
});
})
.catch(error => {
setFormData({
...formData,
loading: false,
errorMsg: error.response.data.errorMessage
});
});
}
}
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
errorMsg: ""
});
}
// View
const showSigninForm = () => (
<form className="signin-form" onSubmit={handleSubmit} noValidate>
<h4 className="d-flex justify-content-center mb-4">Đăng nhập</h4>
{/* email */}
<div className="form-group input-group">
<div className="input-group-prepend">
<span className="input-group-text">
<i className="fa fa-envelope"></i>
</span>
</div>
<input
type="email"
name="email"
value={email}
onChange={handleChange}
className="form-control"
placeholder="Email address"
/>
</div>
{/* password */}
<div className="form-group input-group">
<div className="input-group-prepend">
<span className="input-group-text">
<i className="fa fa-lock"></i>
</span>
</div>
<input
type="password"
name="password"
value={password}
onChange={handleChange}
className="form-control"
placeholder="Password"
/>
</div>
{/* submit */}
<button type="submit" className="btn btn-primary btn-block">Đăng nhập</button>
<p className="forgot-password text-right" style={{color: 'white'}}>
Bạn chưa có tài khoản?
<Link to="/signup" className="ml-2">Đăng ký</Link>
<Link to="/password" className="ml-2">Quên mật khẩu</Link>
</p>
</form>
);
return (
<div className="signin-container">
<div className="row px-4 vh-100">
<div className="signin-form col-sm-8 col-md-6 mx-auto">
{loading && (
<div className="text-center">
{showLoading()}
</div>
)
}
{errorMsg && showErrorMsg(errorMsg)}
{showSigninForm()}
</div>
</div>
</div>
);
};
export default Signin;
你只需要在useEffect中做清理,我认为可以摆脱这个错误。
useEffect(() => {
let isMounted = true; // note mutable flag
if (isAuthenticated() && isAuthenticated().role === 1) {
//! Redirect to Admin dashboard
history.push('/admin/dashboard');
} else if (isAuthenticated() && isAuthenticated().role === 0) {
//! Redirect to User dashboard
history.push('/user/dashboard');
}
return () => { isMounted = false }; // cleanup toggles value, if unmounted
}, [history]);
在我的例子中,我有strayawait sleeps
在我的代码中导致这个错误。
我正在使用react/redux/sagas堆栈,并希望在提交表单时重定向到另一个页面。但是,当我应该在reducer上调用SUCCESS或FAILURE的redux逻辑时,我使用了sleep来检查表单是否成功。