web-dev-qa-db-fra.com

Pourquoi mon onClick est-il appelé lors du rendu? - React.js

J'ai un composant que j'ai créé:

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

Lorsque je render cette page, activatePlaylist est appelé pour chaque playlist de mon map. Si je bindactivatePlaylist aime:

activatePlaylist.bind(this, playlist.playlist_id)

Je peux aussi utiliser une fonction anonyme:

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

alors cela fonctionne comme prévu. Pourquoi cela arrive-t-il?

74
jhamm

Vous devez passer à onClickréférence pour fonctionner, quand vous faites comme ceci activatePlaylist( .. ) vous appelez function et passez à onClick valeur renvoyée de activatePlaylist. Vous pouvez utiliser l'une de ces trois options:

1. en utilisant .bind

activatePlaylist.bind(this, playlist.playlist_id)

2. en utilisant la fonction flèche

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

. ou retourne la fonction de activatePlaylist

activatePlaylist(playlistId) {
  return function () {
     // you code 
  }
}
150
Alexander T.

Ce comportement a été documenté lorsque React a annoncé la publication de composants basés sur des classes.

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

Liaison automatique

React.createClass a une fonctionnalité magique intégrée qui lie automatiquement toutes les méthodes à ceci pour vous. Cela peut être un peu déroutant pour les développeurs JavaScript qui ne sont pas habitués à cette fonctionnalité dans d’autres classes, ou lorsqu’ils passent de React à d’autres classes).

Nous avons donc décidé de ne pas intégrer cela dans le modèle de classe de React. Vous pouvez toujours explicitement pré-relier des méthodes dans votre constructeur si vous le souhaitez.

1
David L. Walsh

Je sais que ce message date déjà de quelques années, mais il suffit de faire référence au dernier React tutoriel/documentation sur cette erreur courante (je l'ai aussi fait)) de https: // reactjs .org/tutorial/tutorial.html :

Remarque

Pour sauvegarder la saisie et éviter le comportement déroutant de cette opération, nous allons utiliser la syntaxe de la fonction de flèche pour les gestionnaires d'événements ici et plus bas:

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

Remarquez comment avec onClick = {() => alert ('click')}, nous passons une fonction en tant que prop de onClick. React n'appelle cette fonction qu'après un clic. Oublier () => et écrire onClick = {alert ('clic')} est une erreur courante et déclenche l'alerte chaque fois que le composant re-rend.

0
CD VA Programmer

La façon dont vous passez la méthode this.activatePlaylist(playlist.playlist_id) appellera immédiatement la méthode. Vous devez passer la référence de la méthode à l'événement onClick. Suivez l'une des implémentations mentionnées ci-dessous pour résoudre votre problème.

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

Ici, la propriété bind est utilisée pour créer une référence du this.activatePlaylist méthode en passant this contexte et argument playlist.playlist_id

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

Cela associera une fonction à l'événement onClick qui ne sera déclenchée que par l'action de clic de l'utilisateur. Quand ce code exécute le this.activatePlaylist la méthode sera appelée.

0
Shrishail Uttagi