reactjsreact-reduxreact-cookie

"Maximum update depth exceeded" error in react and react-cookie


I implemented a simple Login Form in React with Redux following this tutorial: https://jslancer.com/blog/2017/04/27/a-simple-login-flow-with-react-and-redux/

Everything works, but when I add cookies I get the error:

Warning: Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.

and also:

Uncaught Invariant Violation: 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.

I did some debugging and if I remove onChange={e => this.setState({password: e.target.value})} from the inputs in the code below the error disappears.

Any ideas why the following code is not working?

import { connect } from 'react-redux';
import { withCookies } from 'react-cookie'

class LoginForm extends Component {

  constructor(props) {
    super(props);
    this.state = {
      username: '',
      password: ''
    };
  }

  render() {
    let {username, password} = this.state;
    let { cookies, allCookies, isLoginPending, isLoginSuccess, loginError} = this.props;
    cookies.set('username', 'Ross', { path: '/', secure: true, httpOnly: true});
    console.log(cookies.get('username'));
    return (
      <form name="loginForm" onSubmit={this.onSubmit}>
        <div className="form-group-collection">
          <div className="form-group">
            <label>Username:</label>
            <input type="text" name="username" onChange={e => this.setState({username: e.target.value})} value={username}/>
          </div>
          <div className="form-group">
            <label>Password:</label>
            <input type="password" name="password" onChange={e => this.setState({password: e.target.value})} value={password}/>
          </div>
        </div>
      </form>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    isLoginPending: state.isLoginPending,
    isLoginSuccess: state.isLoginSuccess,
    loginError: state.loginError,
  };
}

export default withCookies(connect(mapStateToProps, null)(LoginForm));``` 

Solution

  • My guess is that because your component it connected to the cookies HoC and then you are calling cookies.set in the render method, it is updating itself every time, creating an infinite loop. Please try moving cookies.set to componentDidMount.