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

后端 未结 2 1545
既然无缘
既然无缘 2020-11-29 13:50

Explanation to why this is not a duplicate: My code is already working, I have included as a comment. The question is why the this context change when I include

相关标签:
2条回答
  • 2020-11-29 14:45

    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>

    0 讨论(0)
  • 2020-11-29 14:48

    Bind it in the constructor

    constructor(props) {
        super(props);
        this.inputDigit = this.inputDigit.bind(this);
    }
    
    0 讨论(0)
提交回复
热议问题