2017-06-06 1 views
-1

Explication pourquoi ce n'est pas un doublon: Mon code fonctionne déjà, je l'ai inclus comme commentaire. La question est pourquoi le contexte this change quand je l'inclue pour cliquer sur la fonction de gestionnaire.
J'essaye un projet de calculatrice dans React. Le but est d'attacher les gestionnaires onclick aux boutons numériques afin que les nombres soient affichés sur la zone d'affichage de la calculatrice. Si le gestionnaire est écrit directement dans la méthode de rendu, il fonctionne, cependant, si j'essaie de ComponentDidMount, j'obtiens une erreur this.inputDigit is not a function. Comment lier this.inputDigit(digit) correctement?Comment lier correctement les gestionnaires onclick à `this` sur 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

La duplication possible de [this.setState n'est pas une fonction] (https: // stacko verflow.com/questions/33381756/this-setstate-is-not-a-function) – jmargolisvt

+0

@jmargolisvt Mec j'ai expliqué pourquoi ce n'est pas un doublon, Aussi le message d'erreur est différent. Pourriez-vous désabaisser la question? –

+0

Je ne vous ai pas déprécié. Notez que les réponses que vous obtenez sont les mêmes que celles que j'ai marquées dans le doublon. :) – jmargolisvt

Répondre

3

C'est parce que vous écrivez à l'intérieur d'une fonction qui est pas lié,

Utilisez

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

ou

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

Après cela, vous devez lier la fonction inputDigit car il utilise également setState

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

Puisque vous voulez utiliser le texte du bouton et, dans ce cas, vous devez utiliser une variable distincte à la place de this pour appeler la fonction inputDigit comme

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

Je reçois targetNumber comme NaN –

+0

Qu'est-ce que 'Number (this.innerHTML)' renvoie –

+0

il renvoie NaN –

0

lierai dans le constructeur

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

OP utilise '' plugins '': ["transform-class-properties"] 'pour ne pas avoir à faire cela. La liaison de chaque méthode de composant peut être désordonnée, c'est pourquoi ils utilisent 'state =' au lieu de 'this.state' dans un constructeur. –

+0

'state =' n'est pas dans un constructeur et vous n'avez pas besoin de le faire pour chaque méthode. Juste celui dont vous avez besoin pour effectuer un rappel ou toute fonction qui peut changer de contexte. – digitake