web-dev-qa-db-fra.com

ReactJS - comment transmettre des données "globales" à des composants enfants profondément imbriqués?

Comment les gens abordent-ils généralement le fait d'avoir des données "globales" dans une application React?

Par exemple, supposons que je dispose des données suivantes pour un utilisateur une fois connecté à mon application.

user: {
  email: '[email protected]',
  name: 'John Doe'
}

Il s'agit de données que presque tous les composants de mon application peuvent vouloir connaître - ils peuvent donc s'afficher dans un état connecté ou déconnecté, ou peut-être afficher l'adresse e-mail des utilisateurs s'ils sont connectés.

D'après ma compréhension, la manière React d'accéder à ces données dans un composant enfant consiste à ce qu'un composant de niveau supérieur possède les données et les transmette aux composants enfants à l'aide de propriétés, par exemple:

<App>
  <Page1/>
  <Page2>
    <Widget1/>
    <Widget2 user={user}/>
  </Page2>
</App>

Mais cela me semble compliqué, car cela signifierait que je devrais passer les données à travers chaque composite, juste pour les transmettre à l'enfant qui en a besoin.

Existe-t-il une React façon de gérer ce type de données?

Remarque: Cet exemple est très simplifié - j'aime envelopper les intentions sous forme de composites afin que les détails d'implémentation de toutes les fonctionnalités de l'interface utilisateur puissent être radicalement modifiés comme je l'entends.

[~ # ~] modifier [~ # ~] : je suis conscient que par défaut, appelant setState sur mon composant de niveau supérieur entraînerait le rendu de tous les composants enfants , et que dans chaque composant enfant, je peux rendre en utilisant toutes les données que j'aime (par exemple, les données globales, pas seulement l'état ou les accessoires). Mais comment les gens choisissent-ils de notifier uniquement certains composants enfants qu'ils doivent être rendus?

44
Brad Parks

Depuis que j'ai répondu à l'origine à cette question, il est devenu évident pour moi que React lui-même ne prend en aucun cas en charge les données "globales" - il est vraiment destiné à gérer l'interface utilisateur et c'est tout. Les données de votre application doit vivre ailleurs. Cela dit, elle prend désormais en charge l'accès aux données globales contextcomme détaillé dans cette autre réponse sur cette page . Ce dépôt ( Non déclaré ) résume censément context d'une manière plus agréable, pour ceux qui sont intéressés, et voici un bon article de Kent Dodds sur la façon dont le context api a évolué et est désormais officiellement pris en charge dans React.

L'approche context ne doit être utilisée que pour des données véritablement globales. Si vos données entrent dans une autre catégorie, vous devez procéder comme suit:

  • Facebook résout lui-même ce problème en utilisant sa propre bibliothèque Flux .
  • Mobx et Redux sont similaires à Flux, mais semblent avoir un attrait plus populaire. Ils font la même chose, mais d'une manière plus propre et plus intuitive.

Je laisse mes modifications originales à cette réponse ci-dessous, pour un peu d'histoire.

ANCIENNE RÉPONSE:


https://github.com/dustingetz/react-cursor

et cette bibliothèque similaire:

https://github.com/mquan/cortex

NOTE MAJEURE: I pensez c'est un travail pour Flux de Facebook , ou quelque chose de similaire (ce qui est ci-dessus). Lorsque le flux de données devient trop complexe, un autre mécanisme est nécessaire pour communiquer entre les composants autres que les rappels, et Flux et ses clones semblent l'être ...

17
Brad Parks

Utilisez la React Context Property Ceci est spécifiquement destiné à transmettre des ensembles de données globales le long de la chaîne sans les transmettre explicitement. Cependant, cela complique les fonctions du cycle de vie de vos composants et notez les précautions proposées sur la page que j'ai liée.

11
Steve Taylor

Vous pouvez utiliser React Context API pour transmettre des données globales aux composants enfants profondément imbriqués. Kent C. Dodds a écrit un article détaillé sur Medium React’s ⚛️ new Context API . Cela vous aidera à mieux comprendre comment utiliser l'API.

2
mukeshmandiwal

Quel est le problème avec le simple fait de transmettre des données tout au long de la chaîne de composants via le rendu de tous les enfants avec {... restOfProps}?

render(){
  const {propIKnowAbout1, propIKnowAbout2, ...restOfProps} = this.props;
  return <ChildComponent foo={propIKnowAbout1} bar={propIKnowAbout2} {...restOfProps}/>
}
1
BoxerBucks