如何防止用户对登录表单的多次单击提交按钮错误做出反应? [英] How to prevent user multiple click submit button error for a login form in react?
问题描述
我将formik和react-router-dom用于我的React登录管理.但是,如果在短时间内多次单击提交"按钮,则重定向到主页后,将出现以下错误:警告:无法在已卸载的组件上执行React状态更新.这是无操作,但表明您的应用程序存在内存泄漏.要修复,取消componentWillUnmount方法中的所有订阅和异步任务.在SignInForm中(由Route创建)在路线中(在App.js:52)"重定向后主页将为空数据.
I use formik and react-router-dom for my react login management. 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.
我尝试使用formik的setSubmitting(false)禁用该按钮,但是,如果用户输入错误的密码,该按钮也会被禁用.我是否可以知道我的代码有什么问题,什么是处理这种登录情况的好方法?非常感谢!
I try to use setSubmitting(false) of formik to disable the button, how ever, if user enter wrong password, the button is also disabled. 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 >
推荐答案
可能的解决方案是移动setSubmitting(false);.到帖子之前(如果它不会终止帖子):
A possible solution may be to move the 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;
然后将axios.post块包装在if语句中,并在忙时将变量设置为true,并在完成时将其设置为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:
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;
})
}
}}
这篇关于如何防止用户对登录表单的多次单击提交按钮错误做出反应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!