2015-04-07 3 views
8

В this tutorial он использует функцию onClick со связыванием.В React, почему мне нужно привязать функцию onClick, а затем вызвать ее?

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

Когда я удалить привязывать как этот

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

Я получаю ошибку

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.

Я знаю, что bind делает, но зачем он нужен здесь? Действительно ли onClick не вызывает функцию напрямую?

(код в этом JSbin: https://jsbin.com/gutiwu/1/edit)

ответ

7

Он использует bind так, что метод deletePerson получает правильный person аргумент.

Поскольку компонент Card не получает полный объект Person, это позволяет ему идентифицировать, на чьей персоне была нажата карта.

В вашем примере, где вы удалили привязку onClick={that.deletePerson(person)}, фактически оценивает функцию that.deletePerson(person) и устанавливает это как onClick. Метод deletePerson изменяет состояние компонента, что и говорит сообщение об ошибке. (Вы не можете изменить состояние во время рендера).

Лучшим решением может быть передача идентификатора в Карту и передача его обратно в компонент приложения при щелчке по удалению.

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