2015-04-07 11 views
8

In this tutorial er verwendet eine onClick-Funktion mit Bindung.Warum muss ich in React eine onClick-Funktion binden und dann aufrufen?

<Card onClick={that.deletePerson.bind(null, person)} name={person.name}></Card> 

Wenn ich entferne die Bindung wie diese

<Card onClick={that.deletePerson(person)} name={person.name}></Card> 

Ich erhalte einen Fehler

Uncaught Error: Invariant Violation: setState(...): Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.

Ich weiß, was bind tut, aber warum ist es hier notwendig? Ruft die onClick die Funktion nicht direkt auf?

(Code ist in diesem JSbin: https://jsbin.com/gutiwu/1/edit)

Antwort

7

Er hat die bind so verwendet, dass die deletePerson Methode ruft die richtige person Argument.

Da die Card Komponente kein vollständiges Person Objekt erhält, kann er damit identifizieren, auf welche Person die Karte tatsächlich geklickt wurde.

In Ihrem Beispiel, wo Sie die Bindung entfernt onClick={that.deletePerson(person)} ist tatsächlich die Funktion that.deletePerson(person) auswerten und das als onClick einstellen. Die deletePerson Methode ändert den Status der Komponente, was die Fehlermeldung sagt. (Sie können den Status während eines Rendervorgangs nicht ändern).

Eine bessere Lösung könnte darin bestehen, die ID in Card zu übergeben und bei einem Lösch-Klick an die App-Komponente zurück zu senden.

var Card = React.createClass({ 
    handleClick: function() { 
    this.props.onClick(this.props.id) 
    } 
    render: function() { 
     return (
      <div> 
       <h2>{this.props.name}</h2> 
       <img src={this.props.avatar} alt=""/> 
       <div></div> 
       <button onClick={this.handleClick}>Delete Me</button> 
      </div> 
    ) 
    } 
}) 

var App = React.createClass({ 

    deletePerson: function (id) { 
    //Delete person using id 
    }, 

    render: function() { 
    var that = this; 
    return (
     <div> 
      {this.state.people.map(function (person) { 
       return (
        <Card onClick={that.deletePerson} name={person.name} avatar={person.avatar} id={person.id}></Card> 
       ) 
      }, this)} 
      </div> 
    ) 
    } 
})