2017-06-06 62 views
-1

解释为什么这不是重复的:我的代码已经工作,我已经包含在注释中。问题是为什么当我将它包含到点击处理函数时,this上下文发生了变化。
我正在尝试React中的计算器项目。目标是将onclick处理程序附加到数字按钮,以便数字显示在计算器显示区域中。如果处理程序直接写入渲染方法,则它正在工作,但是,如果我尝试从ComponentDidMount中收到错误this.inputDigit is not a function。我如何正确绑定this.inputDigit(digit)如何将onclick处理程序正确地绑定到`this`上React

import React from 'react'; 
import './App.css'; 

export default 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 myFunction = function() { 
    var targetNumber = Number(this.innerHTML); 
    return this.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-keys1">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> 
) 
} 
} 
+0

[this.setState不是函数]的可能副本(https:// stacko verflow.com/questions/33381756/this-setstate-is-not-a-function) – jmargolisvt

+0

@jmargolisvt Dude我已经展开了为什么它不是重复的,也是错误信息是不同的。你可以不要低估这个问题吗? –

+0

我没有让你失望。请注意,您收到的答案与我在副本中标记的答案相同。 :) – jmargolisvt

回答

3

那是因为你这是不绑定的功能,

使用里面写它

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

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

此之后,你需要绑定的inputDigit功能以及因为它也使用setState

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

既然你要使用的按钮上的文字为好,在这种情况下,你应该使用一个单独的变量代替this调用inputDigit功能类似

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

我得到的目标编号为NaN –

+0

'Number(this.innerHTML)'返回 –

+0

它返回NaN –

0

将其绑定在构造函数中

constructor(props) { 
    super(props); 
    this.inputDigit = this.inputDigit.bind(this); 
} 
+0

OP正在使用''plugins“:[”transform-class-properties“]'不必这样做。绑定每个组件方法可能会变得混乱,这就是为什么他们在构造函数中使用'state ='而不是'this.state'。 –

+0

'state ='不在构造函数中,你不需要为每一种方法都这样做。只需要您执行回调或任何受上下文更改影响的功能。 – digitake

相关问题