web-dev-qa-db-fra.com

React: événement qui bouillonne dans les composants imbriqués

Disons que j'ai des composants imbriqués comme ceci:

<root />
  <comp1 />
    <comp2 />
      <target id={this.props.id}>
        <div>click me</div>

Je veux faire en cliquant sur la cible exécuter une fonction sur la racine:

//on root component
this.action = function(id){}

Dois-je définir manuellement une propriété sur chaque composant de la chaîne, comme dans l'exemple du didacticiel React? Jsfiddle

<root />
  <comp1 clickHandler={this.action}/>
    <comp2 clickHandler={this.clickHandler}/>
      <target id={this.props.id} clickHandler={this.clickHandler} />
        <div onClick={this.props.clickHandler.bind(this, this.props.id)}>click me</div>

Ou y a-t-il un moyen de bouleverser les événements comme dans un DOM normal?

18
kapsi

Vous pouvez utiliser le raccourci pour transmettre des accessoires aux composants enfants.

<Component {...this.props} more="values" />

Transfert des accessoires

Donc dans votre cas:

<root />
  <comp1 clickHandler={this.action}/>
    <comp2 {...this.props} />
      <target {...this.props} id={this.props.id} />
        <div onClick={this.props.clickHandler.bind(this, this.props.id)}>click me</div>
4
Clarkie

React prend en charge les événements synthétiques dans son DOM virtuel lors des phases de capture et de bullage (comme décrit ici: https://facebook.github.io/react/docs/events.html ).

Cela signifie que vous pouvez placer un gestionnaire onClick sur tout élément DOM situé près de la racine et qu'il doit déclencher tous les événements Click de la page:

<root>
  <div onClick={this.handleAllClickEvents}>
    <comp1>
      <comp2>
        <target>
          <div id={this.props.id}>click me</div>

Cependant, comme il va se déclencher pour les événements de clic all, vous devez les distinguer dans le gestionnaire de clics (ce qui donne un code assez moche).

function handleAllClickEvents(event) {
  var target = event.relatedTarget;
  var targetId = target.id;
  switch(targetId) {
    case 'myBtn1':
      // handle myBtn1 click event
    case 'myBtn2':
      // handle myBtn2 click event
  }
}

Ce style de délégation d’événement est en réalité ce que React fait sous le capot ( https://shripadk.github.io/react/docs/interactivity-and-dynamic-uis.html#under-the-hood-autobinding-and- event-delegation ) vous devez donc vous demander si c'est ce que vous voulez vraiment faire.

Vous pouvez également consulter le modèle Dispatcher dans Flux ( https://reactjs.org/blog/2014/07/30/flux-actions-and-the-dispatcher.html ). C'est un peu plus compliqué d'y aller mais c'est globalement une meilleure solution.

29
chrismilleruk

Si vous voulez distinguer quel élément a été cliqué à la fin, vous pouvez utiliser un objet Event et y trouver des informations intéressantes, telles que le type d'élément DOM.

<AnElement>
 <button onClick={e => this.eventHandler(e)}>Click me</button>
 <input type="text" onClick={e => this.eventHandler(e)}>Click me</input>

eventHandler = (e) => {
        console.log(e, e.nativeEvent.toElement.nodeName);
...}

Et vous obtenez button ou input en fonction de ce que vous avez cliqué . C'est ce que j'ai recherché pour mon projet. 

De plus, vous pouvez trouver une arborescence DOM dans une représentation sous forme de tableau  array representation

J'espère que ça aide

0
AlexNikonov