javascript reactjs this

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>