Réagir: quelle est la bonne manière de passer une ref à une béquille?
Je suis en train de passer une ref d'un composant à un autre composant. Depuis chaîne de refs sont désapprouvées je suis en utilisant le rappel réf.
Donc, j'ai quelque chose de similaire à ceci:
<One ref={c => this.one = c}/>
<Two one={this.one}/>
Le problème est qu'à chaque fois que j'essaie d'accéder à this.props.one
à l'intérieur de Two
- je obtenir undefined
.
J'ai même essayé ce Two
:
componentDidMount(){
setTimeout(()=>{
console.log(this.props.one);
},5000)
}
Il semble que le problème est que, lorsque l'hélice est créé, l'arbitre n'existe pas encore car il est créé une fois que One
est monté. Mais je ne sais pas comment faire pour "rafraîchir" les accessoires sur Two
pour obtenir la ref de la montée de la composante.
Donc quelle est la bonne manière de passer une ref à un autre composant?
Modifier
Certains utilisateurs ont suggéré d'encapsuler la logique dans un composant plus élevé, ce qui rend ceux d'autres composants enfants.
Le problème avec cette approche est que vous ne pouvez pas créer de réutilisables logique, et vous devez répéter la même logique dans ceux de l'encapsulation des composants.
Disons que vous voulez créer un générique <Form>
composant qui encapsule les soumettre logique de votre magasin, la vérification des erreurs, etc. Et vous faites quelque chose comme cela:
<Form>
<Input/>
<Input/>
<Input/>
<Input/>
<SubmitButton/>
</Form>
Dans cet exemple <Form>
ne peut pas accéder aux instances (et les méthodes) de l'enfant depuis this.props.children
n'est pas le retour de ces instances. Il retourne quelques liste de pseudo composants.
Alors, comment pouvez-vous vérifier si un certain <Input/>
a détecté une erreur de validation sans passer un ref?
Vous avez pour encapsuler les composants dans un autre composant avec la logique de validation. Par exemple, dans <UserForm>
. Mais étant donné que chaque forme est différente de la même logique doit être copié dans <CategoryForm>
, <GoupForm>
, etc. C'est terriblement inefficace, c'est pourquoi je veux pour encapsuler la logique de validation dans <Form>
et de passer des références de la <Input>
composants <Form>
.
Parce que j'ai besoin de passer l'instance du composant afin que je puisse appeler ses méthodes. À l'aide de rappel refs n'est pas contre les règles: facebook.github.io/react/docs/more-about-refs.html
Ah, merci pour la clarification. Pour ce cas d'utilisation je vous conseille d'utiliser
context
qui a été conçu pour résoudre ce problème. facebook.github.io/react/docs/context.htmlJ'ai parlé trop vite, le contexte n'a pas permis de résoudre le problème. Contexte permet à l'enfant de référence tapé "propriétés" de plus haut dans l'arbre sans être passé ces propriétés. Il peut aider à l'écriture de composants génériques. Le "reacty" façon de le faire est de déplacer la forme de l'état de l'Entrée des composants. Envisager d'avoir une classe qui représente votre générique de données et de validation de la logique de cette classe encapsule une seule composante d'Entrée, mais est transmis de la mère. Puisque la forme a une liste de ces instances, il peut ignorer l'enfant composants eux-mêmes.
Laissez-nous continuer cette discussion dans le chat.
OriginalL'auteur Pier | 2016-08-10
Vous devez vous connecter pour publier un commentaire.
En général, le "ref" est un anti-modèle à Réagir. Il existe pour permettre à des effets secondaires driven development, cependant, afin de bénéficier le plus de la façon de Réagir de la programmation, vous devriez essayer d'éviter les "arbitres" si possible.
Quant à votre question en particulier, le passage d'un enfant d'une ref à son frère est un poulet vs oeuf scénario. La ref de rappel est déclenché lorsque l'enfant est monté, pas pendant le rendu qui est pourquoi votre exemple ne fonctionne pas. Une chose que vous pouvez essayer de pousser la ref en état, puis la lecture à partir d'un état à l'autre enfant. Donc:
Remarque: sans l'
!this.state.one
cela va provoquer une boucle infinie.Ici est un codepen exemple de ce travail (regardez la console pour voir le frère ref connecté): http://codepen.io/anon/pen/pbqvRA
J'ai mis à jour le code pour afficher seulement la solution qui comprend
!this.state.one
qui fonctionne. La raison setState est nécessaire que le parent composant doit être rendu après la ref rappel des feux. Aussi, cela peut provoquer le comportement bizarre depuis à chaque fois Réagir rend il sera techniquement la construction d'un nouveau réf objet.Je suis d'accepter cela, car il n'répondre à la question.
Les gars, je c'est pas d'aujourd'hui. Vérifier le violon, et de voir qu'il y a un message d'erreur indiquant que le Maximum de la pile des appels dépassé. Toute autre idée comment résoudre ce problème?
À remarquer que dans mon commentaire comment je parle de la boucle infinie de prévention. "Remarque: sans l' !c'.état.un cela va provoquer une boucle infinie."
OriginalL'auteur Carl Sverre
En général, si vous avez besoin de passer une référence à quelque chose qui ne peut être temps d'appel, vous pouvez passer un lambda à la place:
et faire référence à elle comme
Si elle a été fixée, quand vous l'appelez, vous obtiendrez une valeur. Avant cela, vous aurez
undefined
(en supposant qu'il n'a pas été initialisé).Il est à noter que vous n'aurez pas nécessairement rendre à nouveau lorsqu'il est disponible, et je m'attends à ce qu'il soit
undefined
sur le premier rendu. C'est quelque chose qui aide à maintenir votre référence n'gérer, mais vous ne recevrez pas plus d'un nouveau rendu.Compte tenu de tout cela, je voudrais vous recommandons de déplacer n'importe quel code a été en utilisant la réf à
One
dansTwo
dans le composant qui est renduOne
etTwo
, pour éviter tous les problèmes à la fois avec cette stratégie, et celui de @Carl Sverre réponse.OriginalL'auteur Ben Mosher