2017-01-14 3 views
1

Ich habe gerade angefangen, React und JavaScript zu lernen.
Während durch das Tutorial gehe, habe ich zu diesem Beispielcode einer Komponente, die eine Toggle-Button erstellt:Warum eine Funktion erfordert eine Bindung und die andere nicht?

class Toggle extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = {isToggleOn: true}; 
     this.handleClick = this.handleClick.bind(this); 
    } 

    handleClick() { 
     this.setState(prevState => ({ 
      isToggleOn: !prevState.isToggleOn 
     })); 
    } 

    render() { 
     return (
      <button onClick={this.handleClick}> 
       {this.state.isToggleOn ? 'ON' : 'OFF'} 
      </button> 
     ); 
    } 
} 

So wie ich es sehe, beide handleClick und render Funktionen this die Klasse der verwenden Objekt, das ist außerhalb ihrer Reichweite (richtig?).

Also warum muss ich nur in handleClick binden?

+0

Ich habe nie reagiert, aber meine Vermutung ist, dass der 'onClick' Funktionsaufruf das' this' Schlüsselwort durch das 'window' Objekt oder etwas ähnliches ersetzt. Dies geschieht tatsächlich mit der Standardmethode 'addEventListener', die den Callback mit' this' = 'window' aufruft. Wahrscheinlich weil "handeClick" vom "Fenster" aufgerufen wird, muss das 'this' Schlüsselwort gebunden werden, so dass es nicht von' window' überschrieben wird oder wer auch immer die click Funktion aufruft. – Cristy

Antwort

1

In jeder Reaktionsklasse werden Funktionen wie componentWillMount, componentDidMount, render usw. aufgerufen, die beim Rendern der Elemente intern reagieren und wir rufen diese Methoden nie auf.

Jetzt, da der Umfang beim Aufruf entschieden wird, ist es die Aufgabe der Reaktion, diese Methoden mit dem entsprechenden Umfang aufzurufen/zu binden. Daher müssen wir uns nicht um diese Funktionen kümmern.

Allerdings sind die anderen Funktionen wie handleClick im obigen Beispiel eine von uns erstellte Methode und reagieren darauf nicht. Auch der Aufruf dieser Methode wird von uns definiert (d. H. Wenn auf die Schaltfläche geklickt wird). Hier ist es unsere Aufgabe, diese Methode mit dem richtigen Umfang aufzurufen/zu binden.

Aus diesem Grund binden wir im obigen Beispiel nur handleClick und nicht die Renderfunktion.

2

Javascript weist den Bereich beim Aufruf zu, nicht beim Definieren. Sie müssen bind() Ihre handleClick()-Methode für die Klasse, so dass, wenn es von der Vorlage aufgerufen wird, kann es weiterhin Zugriff auf die Klasse 'Bereich über this.

Reagieren Vorlagen sind in JavaScript-Funktionen kompiliert, also wenn Sie nicht bind() Ihre onClick={this.handleClick} Handler wäre auf die Vorlage Funktion, die es genannt wurde. In Ihrem Fall würde es sich auf die Schaltfläche beziehen, auf die geklickt wurde.

Wenn Ihr Event-Handler nie auf this verwiesen hat, wäre keine Bindung erforderlich, aber da Sie this.setState() aufrufen, ist eine Bindung erforderlich, um den Handler über den Klassenbereich zu informieren.

+0

Ich glaube, dass "this" sonst auf die Schaltfläche verweisen würde, die das Ereignis ausgelöst hat. – sweaver2112

+0

@ sweaver2112 danke, ich habe meine Antwort aktualisiert, um das klarer zu machen. – Soviut

+0

Ist 'render()' nicht die "Template-Funktion, die es aufgerufen hat", und nicht die Schaltfläche? Und 'render()' ist in der gleichen Klasse, also soll es das gleiche "this" teilen? – user3134477

Verwandte Themen