Reputation: 189
I'm facing an 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.
My code is:
class Login extends React.Component {
constructor(props){
super(props);
this.state = {
firstName: '',
password: '',
isLogged: false
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChangeFirstName = this.handleChangeFirstName.bind(this);
this.handleChangePassword = this.handleChangePassword.bind(this);
}
handleChangeFirstName(event) {
this.setState({firstName: event.target.value})
}
handleChangePassword(event) {
this.setState({password: event.target.value})
}
handleSubmit(event) {
console.log('login');
console.log('first name:' ,this.state.firstName);
console.log('password:' ,this.state.password);
this.props.loginRequest(this.state.firstName, this.state.password);
// console.log('login',this.props)
}
componentDidUpdate() {
if(this.props.request.message === 'ok'){
console.log('ok');
this.setState({isLogged: true});
this.props.history.push('/');
//path is ok!!!
console.log('path from history: ', this.props.history);
}
}
render() {
return(
<div>
{this.state.isLogged ? <App />
:
<div className="container">
<div className="row">
<div className="col-sm-5 log-style">
<div className="log-title">
<h2>Admin Login</h2>
<p>Please enter you login details</p>
</div>
<div className="row p-2">
<input
type="text"
id="fname"
onChange={this.handleChangeFirstName}
className="form-control input-sm"
placeholder="First name"
style={{'border':'none'}} required/>
</div>
<div className="row p-2">
<input
type="password"
id="pass"
onChange={this.handleChangePassword}
className="form-control input-sm"
placeholder="Password"
style={{'border':'none'}} required/>
</div>
<div className="row" style={{'marginTop':'40px'}}>
<div className="col-sm-6" style={{'padding': '2px'}}>
<input type="checkbox"
style={{
'float': 'left',
'marginTop': '10px',
'marginLeft': '13px'
}} />
<label
style={{
'marginTop': '7px',
'marginLeft': '9px'
}}>Remember me </label>
</div>
<div className="col-sm-6"
style={{
'paddingTop': '7px',
'textAlign': 'right'
}}>
<a href="#"
style={{
'color': 'purple',
'fontSize': '13px'
}}>
Forgot password?</a>
</div>
</div>
<div className="row" style={{'justifyContent': 'center'}}>
<div className="btn btn-sm borderBtn"
style={{
'backgroundColor':'purple'}}
onClick={() => this.handleSubmit(event)}>
<span className="fi-account-login">Login</span>
</div>
</div>
</div>
</div>
</div>
}
</div>
)
}
}
const mapStateToProps = state => (
{ user: state.userReducer.user, request: state.userReducer.request }
);
const mapDispatchToProps = dispatch =>
bindActionCreators({loginRequest}, dispatch);
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Login));
I have another component which uses Router to switch pages, and a mail component in which includes Login page.
Upvotes: 5
Views: 34628
Reputation: 553
The problem is every time you component updates, you are updating it again without any kind of break condition. This creates an infinite loop. You should check that this.state.isLogged
is NOT true before updating it here:
componentDidUpdate() {
if(this.props.request.message === 'ok'){
console.log('ok');
if (!this.state.isLogged) {
this.setState({
isLogged: true
});
}
this.props.history.push('/');
//path is ok!!!
console.log('path from history: ', this.props.history);
}
}
This prevents updating the isLogged state when it's already true.
Upvotes: 10