Appeler la méthode de l'enfant du parent

j'ai deux composants.

  1. composant Parent
  2. composant enfant

j'essayais D'appeler la méthode de l'enfant de Parent, j'ai essayé de cette façon, mais n'a pas pu obtenir un résultat

class Parent extends Component {
  render() {
    return (
      <Child>
        <button onClick={Child.getAlert()}>Click</button>
      </Child>
      );
    }
  }

class Child extends Component {
  getAlert() {
    alert('clicked');
  }

  render() {
    return (
      <h1 ref="hello">Hello</h1>
    );
  }
}

y a-t-il un moyen d'appeler la méthode de l'enfant du parent ?

Note: les composantes enfant et Parent se trouvent dans deux fichiers différents

180
demandé sur luke_aus 2016-06-21 19:34:48

5 réponses

vous pouvez utiliser réfs :

class Parent extends Component {
  constructor(props) {
    super(props);
    this.child = React.createRef();
  }

  onClick = () => {
    this.child.current.getAlert();
  };

  render() {
    return (
      <div>
        <Child ref={this.child} />
        <button onClick={this.onClick}>Click</button>
      </div>
    );
  }
}

class Child extends Component {
  getAlert() {
    alert('getAlert from Child');
  }

  render() {
    return <h1>Hello</h1>;
  }
}

ReactDOM.render(<Parent />, document.getElementById('root'));

Exemple De Fonctionnement


j'ai mis à jour cet exemple pour refléter les changements dans React 16.3, qui utilise une nouvelle méthode de manipulation des références. J'ai laissé la version de rappel originale ci-dessous, car elle fonctionne toujours. (Je vais ramener les intégrer ici dès que je reçois Réagir 16.3 et fonctionnant sur Pile Extraits)


modifier

Chaîne de refs sont probablement va être obsolète dans le futur, donc voici comment vous pouvez le faire avec callback " refs :

const { Component } = React;
const { render } = ReactDOM;

class Parent extends Component {
  render() {
    return (
      <div>
        <Child ref={instance => { this.child = instance; }} />
        <button onClick={() => { this.child.getAlert(); }}>Click</button>
      </div>
    );
  }
}

class Child extends Component {
  getAlert() {
    alert('clicked');
  }

  render() {
    return (
      <h1>Hello</h1>
    );
  }
}


render(
  <Parent />,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>
248
répondu rossipedia 2018-04-04 02:40:39

vous pouvez utiliser un autre modèle ici:

class Parent extends Component {
 render() {
  return (
    <div>
      <Child setClick={click => this.clickChild = click}/>
      <button onClick={() => this.clickChild()}>Click</button>
    </div>
  );
 }
}

class Child extends Component {
 constructor(props) {
    super(props);
    this.getAlert = this.getAlert.bind(this);
 }
 componentDidMount() {
    this.props.setClick(this.getAlert);
 }
 getAlert() {
    alert('clicked');
 }
 render() {
  return (
    <h1 ref="hello">Hello</h1>
  );
 }
}

ce qu'il fait est de définir la méthode clickChild du parent lorsque l'enfant est monté. De cette façon, lorsque vous cliquez sur le bouton dans parent il appellera clickChild qui appelle le getAlert de l'enfant.

cela fonctionne aussi si votre enfant est enveloppé de connect() donc vous n'avez pas besoin du hack getWrappedInstance ().

Note vous ne pouvez pas utiliser onClick={this.clickChild} in parent parce que quand parent est rendu enfant n'est pas monté de cette façon.clickChild n'est pas encore assigné. En utilisant onClick= {() = > ceci.clickChild ()} est très bien car lorsque vous cliquez sur le bouton ceci.clickChild devrait déjà être assigné.

38
répondu brickingup 2018-06-12 00:43:18

https://facebook.github.io/react/tips/expose-component-functions.html pour plus de réponses, voir ici méthodes D'appel sur les composants React children

en regardant dans les réfs du composant" raison", vous cassez encapsulation et il est impossible de reformuler ce composant sans examiner attentivement tous les endroits où il est utilisé. Pour cette raison, nous recommandons fortement de traiter les refs comme des civils à une composante, un peu comme de l'état.

en général, les données doivent être transmises dans l'arbre par l'intermédiaire des accessoires. Il y a quelques exceptions (comme l'appel .focus() ou déclencher une animation unique qui ne "change" pas vraiment l'état) mais chaque fois que vous exposez une méthode appelée "set", les accessoires sont généralement un meilleur choix. Essayez de faire en sorte que le composant d'entrée interne s'inquiète de sa taille et de son apparence, ce qu'aucun de ses ancêtres ne fait.

22
répondu Mike Tronic 2017-05-23 12:02:57

si vous faites cela simplement parce que vous voulez que l'enfant fournisse un trait réutilisable à ses parents, alors vous pourriez envisager de faire ce en utilisant des accessoires de rendu à la place.

cette technique retourne en fait la structure à l'envers. Le Child enveloppe maintenant le parent, donc je l'ai renommé en AlertTrait ci-dessous. J'ai gardé le nom Parent pour la continuité, bien qu'il ne soit pas vraiment un parent maintenant.

// Use it like this:

  <AlertTrait renderComponent={Parent}/>


class AlertTrait extends Component {
  // You may need to bind this function, if it is stateful
  doAlert() {
    alert('clicked');
  }
  render() {
    return this.props.renderComponent(this.doAlert);
  }
}

class Parent extends Component {
  render() {
    return (
      <button onClick={this.props.doAlert}>Click</button>
    );
  }
}

dans ce cas, L'AlertTrait fournit un ou plusieurs traits qu'il transmet comme props à quelque élément qu'il ait été donné dans son renderComponent prop.

le Parent reçoit doAlert comme accessoire et peut l'appeler au besoin.

(pour plus de clarté, j'ai appelé le prop renderComponent dans l'exemple ci-dessus. Mais dans les docs React liés ci-dessus, ils l'appellent simplement render .)

le composant Trait peut rendre des trucs entourant le Parent, dans sa fonction de rendu, mais il ne rend rien à l'intérieur du parent. En fait, il pourrait rendre des choses à l'intérieur du Parent, s'il passait un autre prop (par exemple renderChild ) au parent, que le parent pourrait alors utiliser pendant sa méthode de rendu.

C'est quelque peu différent de ce que l'OP demandait, mais certaines personnes pourraient finir ici (comme nous l'avons fait) parce qu'elles voulaient créer un trait réutilisable, et ont pensé qu'une composante enfant était une bonne façon de le faire.

1
répondu joeytwiddle 2018-08-20 07:59:22

vous pouvez faire L'Inversion D'héritage (regardez ici: https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e ). De cette façon, vous avez accès à l'instance du composant que vous emballez (vous pourrez ainsi accéder à ses fonctions)

0
répondu szpada87 2018-08-15 06:46:10