2015-04-07 17 views
8

W this tutorial używa on funkcji onClick z bindem.W React, dlaczego muszę powiązać funkcję onClick zamiast wywoływania go?

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

Kiedy usunąć wiążą się ten

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

pojawia się błąd

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.

wiem co bind robi, ale dlaczego jest tu potrzebny? Czy onClick nie wywołuje bezpośrednio funkcji?

(Kod jest w tym JSbin: https://jsbin.com/gutiwu/1/edit)

Odpowiedz

7

On użyciu bind tak, że metoda deletePerson dostaje prawidłową person argument.

Ponieważ komponent Card nie otrzymuje pełnego obiektu Person, pozwala mu to stwierdzić, która karta rzeczywiście została kliknięta.

W tym przykładzie, w którym usunięto wiązanie onClick={that.deletePerson(person)}, w rzeczywistości analizowano funkcję that.deletePerson(person) i ustawiano jako onClick. Metoda deletePerson zmienia stan składnika, co jest tym, co mówi komunikat o błędzie. (Nie można zmienić stanu podczas renderowania).

Lepszym rozwiązaniem może być przekazanie identyfikatora do karty i przekazanie go z powrotem do komponentu aplikacji po usunięciu kliknięcia.

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> 
    ) 
    } 
})