0

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>
      <input 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

5
  • 1
    this.handleIncrement() should be this.handleIncrement, I think you're constantly rerending the component because of this Commented Nov 12, 2016 at 19:14
  • Don't call this.handleIncrement() and this.handleDecrement() in the render method. Commented Nov 12, 2016 at 19:15
  • i dont understand what you mean about not calling this.handleIncrement() and this.handleDecrement() ?? could you please elaborate ? Commented Nov 12, 2016 at 19:17
  • 1
    You are calling this.handleIncrement() and assigning the return value to onClick. But this.handleIncrement() doesn't return anything. I assume you want to bind this.handleIncrement as event handler itself. As such you have to assign it to onClick, not its return value, i.e. don't call the function, pass it. Commented Nov 12, 2016 at 19:20
  • YES !! that was the mistake i made @FelixKling, also, thank you so much, now i understand what passing a function and passing its return is. Commented Nov 12, 2016 at 19:24

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.