Minouche Bens Minouche Bens - 21 days ago 6
React JSX Question

maximum call stack size exceeded in my reactjs code

I am a beginner in react.js, I am trying to implement a simple fizzbuzz example. Overall, I think I got the gist of how react and its components work, but when I try to run this code on codepen, I get this error:


maximum call stack size exceeded


Here is my code:

class App extends React.Component {
constructor(props){
super(props);
this.state = {
value : '',
number: 0
};
this.handleIncrement = this.handleIncrement.bind(this);
this.handleDecrement = this.handleDecrement.bind(this);
this.fizzBuzz = this.fizzBuzz.bind(this);
}

fizzBuzz(nb){
if(nb % 15 == 0 && nb!= 0)
this.setState({value : `FizzBuzz `});
else if(nb % 5 == 0 && nb!= 0)
this.setState({value : `Buzz `});
else if(nb % 3 == 0 && nb!= 0)
this.setState({value : `Fizz `});
else
this.setState({value : ''});
}

handleIncrement() {
let nb = this.state.number + 1;
this.setState({number: nb});
this.fizzBuzz(nb);
}
handleDecrement() {
let nb = this.state.number-1;
if(nb >= 0)
{ this.setState({number: nb});
this.fizzBuzz(nb);
}
else
{
this.setState({number: 0});
}
}

render() {
return (
<div>
<h1> {this.state.number} </h1>
<h1> {this.state.value} </h1>
<div type="button" value="add" onClick={this.handleIncrement()} />
<input type="button" value="sub" onClick={this.handleDecrement()} />
</div>
);
}
}

ReactDOM.render(<App/>,document.getElementById('app'));


anyone could point out what mistake i did please ? it's been puzzling me for the last two hours.

best regards

Answer

onClick={this.handleIncrement()} means the function handleIncrement is immediately evaluated and its return value is assigned to onClick.

However, handleIncrement updates the component's state by calling this.setState({number: nb}). Every time a component's state is updated, the component is re-rendered. So, in your case, you get a chain of calls render -> handleIncrement -> render -> handleIncrement ... and so on, hence your error (maximum call stack size exceeded).

You don't want the onIncrement method to be evaluated immediately inside the render function. Rather you want it to be evaluated in case of an onClick event. Therefore, you need to pass a reference to the function handleIncrement to your onClick prop.

So, your code should be

<div type="button" value="add" onClick={this.handleIncrement} />

and similar for handleDecrement.

Comments