2017-07-20 2 views
0

Ich kann nicht verstehen, warum this.click = this.click.bind(this) benötigt wird und was es tut.Wie binden "this" für react-Komponente Methode

class MyComponent extends React.Component { 
     constructor(props) { 
      super(props); 
      this.state = { 
       name: 'Initial State' 
      }; 
      this.click = this.click.bind(this); 
     } 
     click() { 
      this.setState({ 
       name: 'React Rocks!' 
      }); 
     } 
     render() { 
     return (
      <div> 
      <button onClick = {this.click}>Click Me</button> 
      <h1>{this.state.name}</h1> 
      </div> 
     ); 
     } 
    }; 

Antwort

4

Wenn Sie nicht Verwendung bind() tat, als this.click() vom Ereignis-Listener genannt wurde, würde der Wert von thisnicht Ihre Reagieren Komponente (state und props usw. sind), aber stattdessen this wäre die Funktion this.click() selbst. Normalerweise wird bei jedem Aufruf einer Funktion der Ausführungskontext - der Wert this - auf die Funktion selbst gesetzt.

Natürlich ist das nicht so eine gute Sache, wenn Sie auf den Kontext Ihrer React-Komponente zugreifen möchten. bind() ist eine Möglichkeit, um sicherzustellen, dass eine Funktion mit demselben Ausführungskontext Ihrer Komponente ausgeführt wird und Sie innerhalb Ihrer Funktion auf this.state, this.props usw. zugreifen können. Eine weitere Möglichkeit ist es, die ES6 Pfeil Funktionsdeklaration zu verwenden:.

let foo =() => {console.log("bar")} 

, die automatisch den Wert von this für foo zu welchem ​​Kontext setzt die Funktion in deklariert wurde Wenn Sie foo im gleichen Kontext erklären als Komponente Reaktion, es behält diesen Kontext und stellt somit sicher, dass der Wert von this innerhalb von foo gleich ist.

+2

Ich möchte nur etwas über es6 Pfeilfunktionen hervorheben und reagieren ... Sie werden eine Menge Beispiele sehen, in denen Leute 'onClick = {() => {_function_body_}}' innerhalb der 'render()' Methode deklarieren . Sie sollten dies nicht tun, da dies zu einem Leistungseinbruch führt, da die Funktion bei jedem Render-Aufruf neu definiert wird. Dies ist nicht das, was @ Jered nur gerade suggeriert. –

+0

Ok, wenn meine Click() - Funktion in ihrem Code nicht "this" verwendet hätte, dann wäre bind nicht nötig, oder? – Sid24

+1

@ Sid24 Das ist richtig. Wenn Ihre Funktion - zum Beispiel - einfach ein Argument verwendet und ein Ergebnis zurückgibt und keinen Zugriff auf Ihren Komponentenstatus, Requisiten oder Funktionen benötigt, müssen Sie diese nicht binden. – jered

2

Sie müssen es tun, weil die Callback-Funktion mit einem anderen context aufgerufen wird. Indem Sie .bind(this) ausführen, stellen Sie sicher, dass die Funktion immer mit derselben thiscontext als Ihre Komponente aufgerufen wird.

Editierte: per @ jered's Kommentar.

+0

Beachten Sie, dass Sie '.bind (this)' nicht verwenden müssen, wenn die Funktion eine Pfeilfunktion ist. – cssko

+0

Sie haben meistens Recht, aber wenn wir von 'this' sprechen, sprechen wir über _context_, nicht _scope_. Kontext und Umfang sind unterschiedliche (wenn auch verwandte) Dinge, sind aber oft füreinander verwechselt, und ich denke, es ist wichtig, die Unterscheidung zu halten. 'bind()' ändert nicht den lexikalischen Umfang der resultierenden Funktion, nur ihren Kontext. – jered

1

Ohne Sie sollten Sie undefiniert werden, wenn Sie Ihre click() Funktion aufrufen. Von der reaktiven Dokumentation ...

Sie müssen in JSX Callbacks auf die Bedeutung von diesem vorsichtig sein. In JavaScript sind Klassenmethoden nicht standardmäßig gebunden. Wenn Sie vergessen, binden Sie this.handleClick ein und übergeben Sie es an onClick, das ist undefined , wenn die Funktion tatsächlich aufgerufen wird.

Schauen Sie sich die Dokumentation für einige weitere Details hier: https://facebook.github.io/react/docs/handling-events.html

2

Gemäß React Documentation Bindung ist erforderlich, da Klassenmethoden nicht standardmäßig gebunden sind. Und wenn Sie einen Rückruf an einen Event-Handler ohne Bindung übergeben, ist 'dies' undefiniert.

Sie Eigenschaft initializers verwenden können, um Rückrufe zu binden:

class MyComponent extends React.Component { 
 
    constructor(props) { 
 
     super(props); 
 
     this.state = { 
 
      name: 'Initial State' 
 
     }; 
 
    } 
 
    handleClick =() => { 
 
     this.setState({ 
 
      name: 'React Rocks!' 
 
     }); 
 
    } 
 
    render() { 
 
     return (
 
      <div> 
 
      <button onClick = {this.handleClick}>Click Me</button> 
 
      <h1>{this.state.name}</h1> 
 
      </div> 
 
    ); 
 
    } 
 
};

Sie können auch eine Pfeil Funktion in den Rückruf verwenden:

class MyComponent extends React.Component { 
 
    constructor(props) { 
 
     super(props); 
 
     this.state = { 
 
      name: 'Initial State' 
 
     }; 
 
    } 
 
    handleClick() { 
 
     this.setState({ 
 
      name: 'React Rocks!' 
 
     }); 
 
    } 
 
    render() { 
 
     return (
 
      <div> 
 
      <button onClick = {() => this.handleClick()}>Click Me</button> 
 
      <h1>{this.state.name}</h1> 
 
      </div> 
 
    ); 
 
    } 
 
};

Verwandte Themen