How to bind onclick handlers to `this` properly on React

Thats because you are writing it inside a function which is not bound,

Use

var myFunction = function() {
    var targetNumber = Number(this.innerHTML);
    return this.inputDigit(targetNumber); 
  }.bind(this);

or

const myFunction = () => {
    var targetNumber = Number(this.innerHTML);
    return this.inputDigit(targetNumber); 
}

After this you need to bind the inputDigit function as well since it also uses setState

//click handler function
inputDigit = (digit) => {
  const { displayValue } = this.state;
  this.setState({
    displayValue: displayValue+String(digit)
  })
}

Since you want to use the button text as well, in that case you should use a separate variable in place of this to call the inputDigit function like

class Calculator extends React.Component {

// display of calculator initially zero
state = {
  displayValue: '0'
}

//click handler function
inputDigit(digit){
  const { displayValue } = this.state;
  this.setState({
    displayValue: displayValue+String(digit)
  })
}

componentDidMount(){

  //Get all number keys and attach click handler function
  var numberKeys = document.getElementsByClassName("number-keys");
  var that = this;
  var myFunction = function() {
    var targetNumber = Number(this.innerHTML);
    console.log(targetNumber);
    return that.inputDigit(targetNumber); // This is not working
  };
  for (var i = 0; i < numberKeys.length; i++) {
    numberKeys[i].onclick = myFunction;
  }

}

render() {
  const { displayValue } = this.state;
  return (
    <div className="calculator">
      <div className="calculator-display">{displayValue}</div>
      <div className="calculator-keypad">
        <div className="input-keys">

          <div className="digit-keys">
            {/*<button className="number-keys" onClick={()=> this.inputDigit(0)}>0</button> This will Work*/}
            <button className="number-keys">0</button>                
            <button className="number-keys">1</button>
            <button className="number-keys">2</button>
            <button className="number-keys">3</button>
            <button className="number-keys">4</button>
            <button className="number-keys">5</button>
            <button className="number-keys">6</button>
            <button className="number-keys">7</button>
            <button className="number-keys">8</button>
            <button className="number-keys">9</button>
          </div>
        </div>          
      </div>
    </div>
  )
 }
} 

ReactDOM.render(<Calculator/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Leave a Comment