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.
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 >
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;
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;
})
}
}}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.