J'ai un composant enfant qui doit écouter l'un de ses événements
parent. Plus précisément, j'ai une fonction dans le composant enfant qui prend comme paramètre un événement
du parent. Je voudrais appeler cette fonction à chaque fois que l ' événement
se produit.
À titre d'exemple, voici un extrait de code:
class Parent extends React.Component { handleKeyDown = (event) => { // Call the child function doSomething() } render() { return ( <input type="text" onKeyDown={this.handleKeyDown} > <Child /> ) } } class Child extends React.Component { doSomething = (event) => { // Get the event from parent } render() { return ( ... ) } }
J'ai considéré deux façons de procéder:
ref
pour appeler la fonction enfant depuis le parent onKeyDown
(en supposant que je puisse y accéder) état
pour stocker l'événement et le transmettre comme accessoires
à l'enfant, puis écouter les modifications des accessoires
avec getDerivedStateFromProps
. Cependant, aucune de ces solutions ne semble très intéressante. J'ai également pensé à utiliser une fonction redux mais j'ai besoin des données du composant enfant ainsi que de l ' événement
du composant parent ... Je me demandais s'il existe un moyen propre de faire cela?
3 Réponses :
Essayez d'appeler doSomething dans la méthode render avant de revenir sur la base des accessoires modifiés, mais cela entraînera une boucle infinie au cas où vous changeriez l'état du composant enfant dans doSomething.
J'ai besoin d'appeler la méthode sur un événement spécifique, pas à chaque fois qu'un accessoire change.
Oui je l'ai eu. Je voulais dire que dans votre parent en cas d'incendie, vous pouvez changer d'état et passer l'état modifié (disons Boolean true) comme accessoire à l'enfant. Dans la méthode de rendu du composant enfant, vous pouvez vérifier si l'état est vrai et appeler doSomething. Dans doSomething, appelez une méthode parente pour redéfinir l'état sur false une fois que vous avez terminé les actions que vous souhaitez effectuer.
J'ai pensé à cette solution aussi, mais elle ne semble pas non plus très propre. : /
C'est vrai. Idéalement, le parent ne devrait pas appeler les méthodes enfants, l'enfant devrait appeler les méthodes parents. Il s'agissait simplement d'une solution de contournement au cas où il serait important pour vous d'appeler une méthode de composant enfant.
Vous pouvez écrire un HOC comme ceci:
const withChild = Wrapped => class Child extends React.Component { doSomething = (event) => { } render() { return ( <React.Fragment> <Wrapped {...this.props} onKeyDown={this.doSomething}/> whatever Child should render </React.Fragment> ) } } const ParentWithChild = withChild(class Parent extends React.Component { handleKeyDown = (event) => { // Call the child function doSomething() if (typeof(this.props.onKeyDown) === 'function') { this.props.onKeyDown(event); } } render() { return ( <input type="text" onKeyDown={this.handleKeyDown} > ) } });
Merci pour votre réponse, je ne connaissais pas HOC. Malheureusement, je ne pense pas que je vais utiliser cette structure, cela semble trop compliqué pour ce que je veux faire.
J'ai décidé d'utiliser la solution fournie par Francis Malloch sur ce post 1 :
class Parent extends React.Component { childCallables = null; setChildCallables = (callables) => { this.childCallables = callables; } handleKeyDown = (event) => { // Call the child function doSomething() this.childCallables.doSomething(event); } render() { return ( <input type="text" onKeyDown={this.handleKeyDown} > <Child setCallables={this.setChildCallables} /> ) } } class Child extends React.Component { componentDidMount() { this.props.setCallables({ doSomething: this.doSomething }); } doSomething = (event) => { // Get the event from parent } render() { return ( ... ) } }
En gros, j'utilise un accessoire pour stocker les méthodes de l'enfant auxquelles j'ai besoin d'accéder depuis le parent. Les méthodes sont enregistrées dans les accessoires juste après le montage du composant enfant.
1. Puisqu'il s'agit d'une réponse à une question complètement différente, je ne pense pas que marquer celle-ci comme un doublon aurait du sens.
Utiliser un accessoire serait la façon dont je le ferais. Les références doivent toujours être un dernier recours.
Il est préférable de déplacer
doSomething
et les données enfants pertinentes versParent
. Si vous avez vraiment besoin d'avoirdoSomething
dans le composantChild
, alorsref
est la meilleure option.@ UjinT34 Heureusement, le composant enfant est très petit et n'est pas destiné à être utilisé ailleurs. J'ai décidé de le mettre séparément car il était plus propre (le composant parent a déjà beaucoup de lignes). Je pense que je ne déplacerai la méthode et les données que si je n'ai pas d'autre choix mais je suis très surpris que React n'ait pas de solution intégrée pour une situation comme celle-ci. 🤔