2
votes

Passer l'événement à travers les composants imbriqués de bas en haut

Bien que cette question ait été posée auparavant, je n'ai pas trouvé de réponse. J'ai des composants imbriqués au niveau de l'arrière-petit-enfant et je ne sais pas comment obtenir les données du bas vers le haut.

<Parent/>
  <Child/>
    <GrandChild/>
      <GreatGrandChild/>

Voir un exemple: violon p >

L'arrière-petit-enfant est un formulaire et je veux que les données d'entrée parviennent au parent en haut. Je l'ai fait fonctionner quand il était juste imbriqué d'un niveau de profondeur, mais maintenant qu'il est profondément imbriqué, cela ne fonctionne pas. Je ne sais pas comment faire passer l'événement de deux niveaux.

J'ai entendu dire que l'utilisation de redux est possible mais je me demande s'il y a un moyen de l'éviter. Ou comment éviter l'emboîtement? Même s'ils sont tous des composants séparés, devrais-je simplement les déplacer en un seul gros composant? Cela pourrait fonctionner mais cela semble être une mauvaise pratique?


3 commentaires

Pour cela, je préfère utiliser l'API de contexte


Merci pour le tuyau. Je le regarde maintenant.


Copie possible de Réagir .js - Comment passer des gestionnaires d'événements à des composants profondément imbriqués sans explorer les accessoires?


4 Réponses :


0
votes

Transmettez simplement un rappel du parent via les accessoires et assurez-vous qu'il est transmis là où vous en avez besoin.


1 commentaires

Depuis que je suis sur mobile, je ne peux pas jeter un œil aux nouvelles réponses ou voir comment cela se fait dans le didacticiel officiel, vous devrez faire la même chose mais deux fois (une fois en passant le rappel à l'enfant et au petit-enfant) reactjs.org/docs/lifting-state-up.html



0
votes

Vous pouvez également transmettre des accessoires à chaque composant enfant lors de l'imbrication et chaque fois que les valeurs changent, vous pouvez appeler une fonction parent (imbriquée) pour obtenir les dernières valeurs dans parent.


0 commentaires

1
votes

Redux est excessif pour le simple passage d'accessoires. Vous pouvez transmettre des accessoires à chaque enfant, mais il est plus facile d'utiliser l ' API de contexte comme ceci: Composant parent:

import { MyContext } from './Parent';

class ChildComponent extends React.Component {
    render() {
        const { myFunction } = this.context;
        return (
            <div onClick={myFunction}>Click Me!</div>
        );
    }
}

ChildComponent.contextType = MyContext;

Composant enfant:

const MyContext = React.createContext('default');
export MyContext;

class Parent extends React.Component {
    myFunction() {
        //Do something here
    }

    render() {
         return (
            <MyContext.Provider value={this.myFunction}>
                <ChildComponent />
            </MyContext.Provider>
         );
    }
}

export default Parent;

Vous pouvez utiliser le contexte aussi profondément que vous le souhaitez , tant que vous l'importez.


0 commentaires

2
votes

Très simplifié, vous pouvez simplement passer la fonction à travers tous les composants:

class GreatGrandChild extends React.Component {
  render() {
    return (
      <div>
      <input onChange={this.props.onChange}/>
        <h2>I'm the GreatGrandChild</h2>
      </div>
    )
  }
}

class GrandChild extends React.Component {
  render() {
    return (
      <div>
        <h2>I'm the GrandChild</h2>
        <GreatGrandChild onChange={this.props.onChange}/>
      </div>
    )
  }
}

class Child extends React.Component {
  render() {
    return (
      <div>
      <GrandChild onChange={this.props.onChange}/>
        <h2>I'm the child</h2>
      </div>
    )
  }
}
class Top extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    }
  }

  handleChildchange = (e) => {
    console.log('child event on parent')
    console.log(e.target.value);
  }
  render() {
    return (
      <div>
       <Child onChange={this.handleChildchange}/>
        <h2>I'm the parent</h2>
      </div>
    )
  }
}

ReactDOM.render(<Top />, document.querySelector("#app"))


2 commentaires

Oui - Mais attention, ce n'est certainement pas la manière la plus élégante. Il est plus élégant d'utiliser les API contextuelles / HoOKs.


Ma situation est assez simple pour que cela suffise. Cependant, pour l'avenir, j'étudierai l'API contextuelle.