1
votes

Partager du contenu entre des composants adjacents, HOC?

J'ai un composant conteneur qui rend deux composants à l'intérieur. En fonction de certains accessoires du conteneur, le composant supérieur peut changer, mais le composant inférieur restera toujours le même.

Je souhaite rendre du contenu supplémentaire (éléments DOM / autres composants de réaction) à l'intérieur du composant inférieur, mais le contenu supplémentaire est créé à l'intérieur du composant supérieur. J'ai du mal à comprendre ce que j'ai besoin de refactoriser ici pour que cela fonctionne. J'ai d'abord essayé de transmettre le contenu créé au conteneur, puis de revenir au composant inférieur. J'ai vite réalisé que cela ne fonctionnait pas car le contenu créé dépend des accessoires / état du composant qui l'a créé.

La création du contenu à l'intérieur du conteneur n'est pas possible car il existe tellement d'options différentes pour le contenu qui peut être créé. La base de code sur laquelle je travaille a 30 à 40 composants possibles qui génèrent tous un contenu différent.

Je suis assez nouveau dans React, donc j'ai du mal à résoudre ce problème de manière réactionnelle. J'ai lu brièvement sur les accessoires de rendu / HOC, c'est peut-être ce dont j'ai besoin ici? Toute aide serait grandement appréciée.

Voici un exemple très basique de ce à quoi il ressemble: https://codesandbox.io/s/zqo2p1yy9m


2 commentaires

Vous pouvez lever l'état et / ou créer le jsx et le passer comme accessoire. Vous n'avez pas besoin de hocs ni d'accessoires de rendu


Oui, comme @ victor.ja l'a mentionné, vous devez améliorer l'état de votre composant. L'article qu'il vous a indiqué est la meilleure explication que vous puissiez obtenir: reactjs.org/docs/ lifting-state-up.html Revenez après l'avoir lu et si vous ne savez toujours pas comment résoudre ce problème, nous pouvons vous aider avec un exemple.


3 Réponses :


1
votes

La nature de la réaction est de haut en bas. Donc, si vous avez besoin de partager une partie de l'état ou des données à passer comme accessoires, vous devez soulever ce code à son parent. C'est bien de passer Jsx comme accessoire, ici vous devez le faire et vous pouvez.

En savoir plus: état de levée

——————

<₹A

/ \

B C

Donc, si vous avez partagé du code entre B et C, vous le portez à A et le transmettez à B et C comme accessoires. Si vous avez besoin de l'état de B à C, vous augmentez l'état à A. Si vous avez besoin d'accéder et de modifier l'état de A à B ou C, il vous suffit de passer une fonction comme rappel à B ou C


0 commentaires

0
votes

Je suis d'accord avec victor.ja mais je me demandais si vous aviez un magasin mondial comme redux. Vous pouvez alors simplement appeler l'action pour mettre à jour l'état du magasin à partir du composant supérieur. Le composant d'ordre supérieur peut recevoir l'état du magasin comme accessoire et mettre à jour le composant inférieur.


0 commentaires

2
votes

Il existe plusieurs façons d'aborder ce problème.

1) Vous pouvez utiliser un système de gestion d'état tel que Redux, mobx ou vous pouvez utiliser l'API contextuelle de React https://reactjs.org/docs/context.html . CEPENDANT, puisque vous êtes assez nouveau dans React, je vous suggère de ne pas vous attaquer à ces bonnes connaissances tant que vous n'êtes pas à l'aise avec le flux de base

2) Vous pouvez implémenter une simple relation parent-enfant code> pour transmettre des données entre les composants. Finalement, cela vous permet de fournir une communication entre les composants adjacents (frères). Comme cela a déjà été dit, ce flux s'appelle généralement la levée de l'État. En fait, les systèmes de gestion étatique fonctionnent de la même manière. Laissez-moi vous expliquer cette logique en prenant également en compte votre exemple de code basé sur un scénario.

Nous aurons un composant Container. Ce composant sera un composant avec état. Le seul but de ce composant Container est d'avoir son propre état holistique, qui sera traité comme la source de vérité par ses enfants. Avoir quelques méthodes pour définir des moyens de mettre à jour cet état holistique. Les composants enfants seront des composants purs ou des composants représentationnels. Cela signifie qu'ils n'auront pas leurs propres états. Ils seront soit utilisés pour afficher les données que leur parent leur transmet, soit pour déclencher des méthodes définies par leur parent afin de mettre à jour la source de l'état de vérité.

Nous aurons deux scénarios: Dans le scénario 1, la liste de contenu sera représentée telle quelle. Dans le scénario 2, la liste de contenu sera représentée en inversant l'ordre des lettres

function ContentDisplayer({ contents, reversed }) {
  return (
    <div className="App">
      {contents.map(content => (
        <div key={content.id}>{reversed ? content.text.split("").reverse().join("") : content.text}</div>
      ))}
    </div>
  );
}

Comme vous pouvez le voir, le conteneur n'a qu'un état, quelques méthodes pour mettre à jour l'état et composant enfant. Pas un seul HTML utilisé à l'intérieur de sa méthode de rendu.

Notre premier composant enfant est ContentCreator

function ContentCreator({
  handleChange,
  handleClick,
  value
  }) {
  return (
    <div className="App">
      <label> New Content</label>
      <input type="text" value={value} onChange={event => handleChange(event.target.value)} />
      <button onClick={handleClick}>Add Content</button>
    </div>
  );
}

function ReversedContentDisplayer({ contents }) {
  return (
    <div className="App">
      {contents.map(content => (
        <div key={content.id}>{content.text.split("").reverse().join("")}</div>
      ))}
    </div>
  );
}

Ce composant agit comme un formulaire (je suis trop paresseux pour l'envelopper avec la forme et la fonction onSubmit). Et le but principal de ce composant est de mettre à jour la clé contents de notre source d'état de vérité

Le deuxième composant est appelé Reversifier (je ne Je ne crois pas qu'il existe un tel mot)

function Reversifier({reversed, handleReverse}) {
  return <button onClick={handleReverse}>{reversed ? 'Back to normal' : 'Reversify'}</button>
}

Le but principal de ce composant est de basculer la clé inversée de notre source d'état de vérité. Vous pouvez également voir que, en fonction de la valeur de inversé , le texte à l'intérieur du bouton change également (reflète une sorte de scénarios différents d'une manière différente)

Et nos deux derniers composants sont

function ContentCreator({
  handleChange,
  handleClick,
  value
  }) {
  return (
    <div className="App">
      <label> New Content</label>
      <input type="text" value={value} onChange={event => handleChange(event.target.value)} />
      <button onClick={handleClick}>Add Content</button>
    </div>
  );
}

Basé sur le scénario, c'est-à-dire s'il affiche le contenu comme normal ou inversé, à l'intérieur de la méthode de rendu de notre composant conteneur, nous affichons l'un ou l'autre. En fait, ces deux composants peuvent être écrits comme un tel que

class Container extends React.PureComponent {
  state = {
    reversed: false,
    newContent: "",
    contents: [
      {
        id: 1,
        text: "Initial Content"
      }
    ]
  };

  handleReverse = () => {
    this.setState((state) => ({
      ...state,
      reversed: !state.reversed
    }))
  }
  submitNewContent = () => {
    this.setState(state => ({
      ...state,
      contents: [
        ...state.contents,
        { id: Math.random(), text: state.newContent }
      ],
      newContent: ""
    }));
  };
  addNewContent = content => {
    this.setState({ newContent: content });
  };

  render() {
    return (
      <React.Fragment>
        <ContentCreator
        value={this.state.newContent}
        handleChange={this.addNewContent}
        handleClick={this.submitNewContent}
        />
        {this.state.reversed ? <ReversedContentDisplayer contents={this.state.contents} /> : <ContentDisplayer contents={this.state.contents} />}
        <Reversifier reversed={this.state.reversed} handleReverse={this.handleReverse}/>
      </React.Fragment>
    );
  }
}

Mais afin de refléter différents scénarios, j'ai créé deux composants distincts

J'ai créé un codesandbox pour vous au cas où vous voudriez jouer avec la fonctionnalité yo voir le résultat final https://codesandbox.io/s / 04rowq150

Ainsi, de cette façon, vous n'avez pas à créer de contenu à l'intérieur du Container , vous pouvez plutôt utiliser Container code > comme ligne directrice en définissant l'état initial et quelques méthodes pour transmettre ses enfants pour leur permettre de créer de nouveaux contenus, et d'afficher ces contenus nouvellement créés au nom du Container

I J'espère que cet échantillon vous aidera comme point de départ et j'espère que je comprends votre exigence au moins 51% correctement. Si vous avez d'autres questions ou confusions, faites-le moi savoir


0 commentaires