I have a simple login component which works fine (i.e it redirects to dashboard most of the times after successful login). However, sometimes out of blue, it throws an error:
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
Here're my code.
Please note that when the error happnens, I notice, <Redirect to={routes.DASHBOARD}/>
this gets called, but instead of redirecting to this component, the same login component keeps getting called infinitely.
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Redirect } from 'react-router';
import { login } from '../../redux/actions';
import styles from './login.module.css';
import {routes} from '../../routes';
export function Login() {
const { user } = useSelector((state) => state);
const dispatch = useDispatch();
const [email, setEmail] =useState('');
const [password, setPassword] = useState('');
const handleLogin = ()=>{
dispatch(login({email, password}))
}
const handleEmailInput = (e)=>{
setEmail(e.target.value)
}
const handlePasswordInput = (e)=>{
setPassword(e.target.value)
}
if((user.tokenReceived || localStorage.getItem('token')) && !user.tokenExpired){
return <Redirect to={routes.DASHBOARD}/>
}
return (
<div>
<div className={styles.row}>
<input type='text' placeholder="Email" onChange={handleEmailInput}/>
<input type='text' placeholder="Password" onChange={handlePasswordInput}/>
<button
className={styles.loginButton}
onClick={handleLogin}
>
Login
</button>
{user.error && "Some Error occurred. Please try again"}
</div>
</div>
);
}
I'm pretty sure I'm doing the right way, but should I be wrapping this under useEffect
,
if((user.tokenReceived || localStorage.getItem('token')) && !user.tokenExpired){
return <Redirect to={routes.DASHBOARD}/>
}
CodePudding user response:
I think your problem lays when you call handleLogin function on button click. Call the function as an arrow function.
<button
className={styles.loginButton}
onClick={() => handleLogin()}
>
CodePudding user response:
Every time you update a state, the page is re-rendered. It means that every time you update a state, this if
is called.
Use a UseEffect to validate data when user just access the page.
useEffect(() => {
if((user.tokenReceived || localStorage.getItem('token')) && !user.tokenExpired){
return <Redirect to={routes.DASHBOARD}/>
}
}, [])