Maifee Ul Asad
Maifee Ul Asad

Reputation: 4607

react.js Maximum update depth exceeded

Here is a piece of code from my NotificationsUnit component :

tem;
notificationsType;
constructor(props)   {
    super(props);
    this.state = {notificationsType:''};
}


render() {
    this.setState({tem: 'btn btn-'});
    return(
        <div>
            <button className='btn btn-info'>
                    onClick={this.createNotification('info')}>Info
            </button>
            <hr/>
        </div>
    );
}

But this gives me error, saying 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 is a snap :

react.js set state problem,maximum depth reached

How can I resolve this?

Upvotes: 0

Views: 904

Answers (3)

goto
goto

Reputation: 4425

The issue is that you're calling this.setState inside of the render method:

render() {
  this.setState({ tem: 'btn btn-' })
  // ...
}

Which is causing your component to re-render infinitely.

You should never call this.setState inside of render. Instead, if you need to update your state based on some event, create another method inside of your component and handle it there.

class NotificationsUnit extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      notificationsType: '',
      tem: 'btn btn-'
    }
  }

  handleSomeEvent = (e) => {
    this.setState({ tem: 'btn btn-' + whatever })
  }

  render() {
    return (
      <div>
        ...
      </div>
    )
  }
}

Also, one thing that I am seeing with the onClick handler of your button:

<button 
  className="btn btn-info"
  onClick={this.createNotification('info')}
>
  Info
</button>

This will end up calling this.createNotification without even clicking the button. Instead, what you probably want to do is this:

<button 
  className="btn btn-info"
  onClick={() => this.createNotification('info')}
>
  Info
</button>

This way, you're creating a function that will get called when onClick handler gets triggered, which then will call the this.createNotification('info') handler, resulting in a correct behavior.

Upvotes: 1

MaartenDev
MaartenDev

Reputation: 5802

You can pass a function to the click handler instead of calling this method directly. Please keep in mind state should never me mutated directly this.state = but should be changed using this.setState()

class NotificationsUnit extends Component {
    state = {
        notificationsType: '',
        tem: 'btn btn-'
    }

    render() {
        const {notificationsType} = this.props
        return (
            <div>
                <button className={'btn btn-' + notificationsType}>
                    onClick={e => this.createNotification('info')}>{notificationsType}
                </button>
                <hr/>
            </div>
        );
    }
}

Example usage:

<NotificationsUnit notificationsType="info"/>

result:

<div>
   <button class='btn btn-info'>info</button>
</div>

Upvotes: 1

ravibagul91
ravibagul91

Reputation: 20755

Never call setState in render function ,

render(){
  this.setState({tem: 'btn btn-'});

  return(
    ...
  )
}

setState leads to re-render of a component, if you place setState in render it will execute on every re-render and you will always get 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.

Instead you can make use of componentDidMount to check this,

componentDidMount(){
   this.setState({tem: 'btn btn-'});
}

Upvotes: 1

Related Questions