javascript - Cómo vincular los controladores onclick a `this` correctamente en React
reactjs (2)
Explicación de por qué esto no es un duplicado: mi código ya está funcionando, lo he incluido como comentario.
La pregunta es por qué cambia
this
contexto cuando lo incluyo para hacer clic en la función de controlador.
Estoy intentando un proyecto de calculadora en React.
El objetivo es adjuntar controladores onclick a los botones numéricos para que los números se muestren en el área de visualización de la calculadora.
Si el controlador está escrito directamente en el método de representación, está funcionando, sin embargo, si lo intento desde ComponentDidMount me sale un error
this.inputDigit is not a function
.
¿Cómo
this.inputDigit(digit)
correctamente?
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>
)
}
}
Atarlo en el constructor
constructor(props) {
super(props);
this.inputDigit = this.inputDigit.bind(this);
}
Eso es porque lo estás escribiendo dentro de una función que no está vinculada,
Utilizar
var myFunction = function() {
var targetNumber = Number(this.innerHTML);
return this.inputDigit(targetNumber);
}.bind(this);
o
const myFunction = () => {
var targetNumber = Number(this.innerHTML);
return this.inputDigit(targetNumber);
}
Después de esto, también debe vincular la función inputDigit, ya que también usa setState
//click handler function
inputDigit = (digit) => {
const { displayValue } = this.state;
this.setState({
displayValue: displayValue+String(digit)
})
}
Como también desea usar el texto del botón, en ese caso debe usar una variable separada en lugar de
this
para llamar a la función inputDigit como
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>