Подтвердить что ты не робот

Почему мой onClick вызывается для рендера? - React.js

У меня есть компонент, который я создал:

class Create extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    var playlistDOM = this.renderPlaylists(this.props.playlists);
    return (
      <div>
        {playlistDOM}
      </div>
    )
  }

  activatePlaylist(playlistId) {
    debugger;
  }

  renderPlaylists(playlists) {
    return playlists.map(playlist => {
      return <div key={playlist.playlist_id} onClick={this.activatePlaylist(playlist.playlist_id)}>{playlist.playlist_name}</div>
    });
  }
}

function mapStateToProps(state) {
  return {
    playlists: state.playlists
  }
}

export default connect(mapStateToProps)(Create);

Когда я render эта страница, activatePlaylist вызывается для каждого playlist в моем map. Если я bind activatePlaylist нравится:

activatePlaylist.bind(this, playlist.playlist_id)

Я также могу использовать анонимную функцию:

onClick={() => this.activatePlaylist(playlist.playlist_id)}

то он работает так, как ожидалось. Почему это происходит?

4b9b3361

Ответ 1

Вам нужно перейти к onClick ссылке, когда вы сделаете это как activatePlaylist( .. ), вы вызываете функцию и передаете значение onClick, которое возвращается из activatePlaylist. Вы можете использовать один из этих трех вариантов:

1. используя .bind

activatePlaylist.bind(this, playlist.playlist_id)

2. используя функцию стрелки

onClick={ () => this.activatePlaylist(playlist.playlist_id) }

3. или возврат из activatePlaylist

activatePlaylist(playlistId) {
  return function () {
     // you code 
  }
}

Ответ 2

Это поведение было зарегистрировано, когда React объявила о выпуске компонентов на основе классов.

https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html

автоматическое связывание

React.createClass имеет встроенную магическую функцию, которая автоматически привязывает все методы к этому автоматически. Это может быть немного запутанным для разработчиков JavaScript, которые не используются для этой функции в других классах, или это может сбивать с толку, когда они переходят из React в другие классы.

Поэтому мы решили не иметь этого встроенного в модель класса React. Вы все еще можете явно использовать методы prebind в своем конструкторе, если хотите.

Ответ 3

Я знаю, что этому посту уже несколько лет, но просто для ссылки на последний учебник/документацию по React об этой распространенной ошибке (я тоже это сделал) из https://reactjs.org/tutorial/tutorial.html:

Примечание

Чтобы сохранить типизацию и избежать путаницы, мы будем использовать синтаксис функции стрелки для обработчиков событий здесь и далее ниже:

class Square extends React.Component {
 render() {
   return (
     <button className="square" onClick={() => alert('click')}>
       {this.props.value}
     </button>
   );
 }
}

Обратите внимание, как с onClick = {() => alert ('click')}, проходили функционировать как onClick проп. React будет вызывать эту функцию только после щелчок. Forgetting() => и запись onClick = {alert ('click')} является распространенная ошибка, и каждый раз выдается предупреждение повторно делает.

Ответ 4

То, как вы передадите метод this.activatePlaylist(playlist.playlist_id), вызовет метод немедленно. Вы должны передать ссылку на метод в событие onClick. Следуйте одной из нижеприведенных реализаций, чтобы решить вашу проблему.

1.
onClick={this.activatePlaylist.bind(this,playlist.playlist_id)}

Здесь свойство bind используется для создания ссылки на метод this.activatePlaylist путем передачи контекста this и аргумента playlist.playlist_id

2.
onClick={ (event) => { this.activatePlaylist.(playlist.playlist_id)}}

Это прикрепит функцию к событию onClick, которая будет запускаться только при нажатии пользователем. Когда этот код работает, будет вызван метод this.activatePlaylist.