[英]How to prevent user multiple click submit button error for a login form in react?
I use formik and react-router-dom for my react login management. 我将formik和react-router-dom用于我的React登录管理。 However, if click the submit button multiple times in a short time, after redirect to home page, there will be an error of "Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method. in SignInForm (created by Route) in Route (at App.js:52)" And the home page will be empty data after redirected.
但是,如果在短时间内多次单击提交按钮,则重定向到主页后,将出现错误消息“警告:无法对已卸载的组件执行React状态更新。这是无操作,但是它表示您的应用程序内存泄漏。要修复,取消componentWillUnmount方法中的所有订阅和异步任务。请在Route(在App.js:52)的SignInForm(由Route创建)中“”重定向。
I try to use setSubmitting(false) of formik to disable the button, how ever, if user enter wrong password, the button is also disabled. 我尝试使用formik的setSubmitting(false)禁用按钮,但是,如果用户输入了错误的密码,该按钮也会被禁用。 May I know what is wrong with my code and what would be a good method to handle this login situation?
我可以知道我的代码有什么问题吗,什么是处理这种登录情况的好方法? Thank you so much!
非常感谢!
if (this.state.redirect) {
return (<Redirect to={'/'} />)
}
if (sessionStorage.getItem('userToken')) {
return (<Redirect to={'/'} />)
}
<Formik
initialValues={{
email: '',
password: ''
}}
validationSchema={Yup.object().shape({
email: Yup.string()
.email()
.required('Required'),
password: Yup.string()
.required('Required'),
})}
onSubmit={(values, { setSubmitting }) => {
axios.post('http://testtesttest/users/sign_in', {
user: {
email: values.email,
password: values.password
}
}).then(res => {
setSubmitting(false);
console.log(res.data);
sessionStorage.setItem('userToken', res.data.auth_token);
sessionStorage.setItem('userId', res.data.id);
this.setState({ redirect: true });
}).catch(err => {
console.log(err);
alert('wrong email address or password');
})
}}
render={formProps => {
return (
<Form className="FormFields">
<div className="form-group ">
<label htmlFor="email" className={this.state.emailActive ? "active" : ""}>Email</label>
<Field
type="text"
name="email"
className={formProps.errors.email && formProps.touched.email ? 'is-invalid form-control' : 'form-control'}
/>
<ErrorMessage name="email"
component="div"
className="invalid-feedback" />
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<Field
type="text"
name="password"
className={formProps.errors.password && formProps.touched.password ? 'is-invalid form-control' : 'form-control'}
/>
<ErrorMessage name="password"
component="div"
className="invalid-feedback" />
</div>
<div className="FormField">
<button
type="submit"
disabled={formProps.isSubmitting }
className="button emit-button emit-button-blue"
>
Submit
</button>
</div>
</Form>
);
}}
/>
<BrowserRouter >
<div className="App">
<Switch>
<PrivateRoute exact path="/" component={Home}>
</PrivateRoute>
<PrivateRoute exact path="/management" component={Management}>
</PrivateRoute>
<PrivateRoute exact path='/quotes/:quoteId(\d+)' component={Quote}></PrivateRoute>
<PrivateRoute exact path='/quotes/new' component={NewQuote}></PrivateRoute>
<PrivateRoute exact path='/cards/:cardId(\d+)' component={CardDetail}></PrivateRoute>
<Route exact path="/sign-up" component={SignUpForm}>
</Route>
<Route exact path="/sign-in" component={SignInForm}>
</Route>
<Route component={Error}>
</Route>
</Switch>
<Footer />
</div>
</BrowserRouter >
A possible solution may be to move the setSubmitting(false); 可能的解决方案是移动setSubmitting(false); to before the post, (if it does not abort the post):
到帖子之前,(如果它不终止帖子):
onSubmit={(values, { setSubmitting }) => {
setSubmitting(false);
axios.post('http://testtesttest/users/sign_in', {
Otherwise, a different solution could be to create a variable higher up to lock the function while it is busy. 否则,另一种解决方案可能是创建一个更高的变量以在函数繁忙时将其锁定。 This will prevent further submissions until it has done its work.
在完成工作之前,这将阻止进一步的提交。
var isSubmitLocked = false;
Then wrap your axios.post block in an if-statement and set the variable to true when busy and back to false when completed: 然后将axios.post块包装在if语句中,并在忙时将变量设置为true,并在完成时将其设置为false:
onSubmit={(values, { setSubmitting }) => {
if(!isSubmitBlocked) {
isSubmitBlocked = true;
axios.post('http://testtesttest/users/sign_in', {
user: {
email: values.email,
password: values.password
}
}).then(res => {
console.log(res.data);
sessionStorage.setItem('userToken', res.data.auth_token);
sessionStorage.setItem('userId', res.data.id);
this.setState({ redirect: true });
isSubmitBlocked = false;
}).catch(err => {
console.log(err);
alert('wrong email address or password');
isSubmitBlocked = false;
})
}
}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.