Почему мой 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)}
то он работает так, как ожидалось. Почему это происходит?
Ответы
Ответ 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
.