web-dev-qa-db-fra.com

Réagir rendre tableau de composants

Question rapide. Quelqu'un sait comment rendre un tableau de composants? Essayer de faciliter la tâche d'un développeur pour modifier un composant particulier. (c'est comme un tableau de bord).

Fichier de liste de composants

import React from 'react';
export default [
    <ComponentOne/>
    <ComponentTwo/>
];

Composant de tableau de bord

import React from 'react';

import components from './../../components';

export default class Dashboard extends React.Component 
{
    render = () => {
        //Want to render the array of components here.
        return (
            <div className="tile is-parent">
                {components}
            </div>
        );
    };
}

Le problème est évidemment que c'est un tableau de composants, donc je dois ajouter une clé. Toutefois! Je ne vois pas comment ajouter une clé au composant aussi ... ... je ne sais pas comment l'expliquer vraiment, alors voici le code que j'ai essayé:

{components.map((component, key) => (
    <component key={key}/>
}

Si je fais ce qui précède, je ne reçois pas d'erreurs 'vous devez appliquer une clé' mais rien ne rend? Et j'imagine que c'est parce que le «composant» n'existe peut-être pas ou quelque chose de bizarre dans ce sens. 

J'ai aussi essayé component.key = key; mais cela ne me permet apparemment pas de le faire sur ce type d'objet? 

Ma solution de remplacement, je suppose, est de renvoyer une fonction abrégée à la place d'un tableau, mais j'aime le tableau pour une raison quelconque? Cela semble plus simple pour les juniors. 

4
sourRaspberri

Avez-vous envisagé d'utiliser le nouveau Réagir Fragments ? (en v16)

Ce serait la solution la plus simple car elle éviterait l’ensemble du problème tableau/clé.

Si vous avez besoin de passer la clé, je suggérerais simplement d'exiger que les composants aient les clés. C’est ainsi que React fonctionne. Je ne vous conseillerais donc pas de cacher ce comportement derrière une interface qui pourrait ne pas être prévisible.

Si vous avez vraiment besoin de faire cela, alors vous pouvez utiliser React.cloneElement pour cloner l'élément et injecter de nouvelles propriétés:

React.cloneElement(element, { key: 'foo' });
2
Simon Boudrias

Si vous souhaitez toujours afficher tous les composants dans votre fichier de composants, il est probablement préférable de les envelopper dans une balise React.Fragments.

La meilleure pratique consiste simplement à exporter ceci en tant que fonction simple qui renvoie les composants plutôt qu'en tant que constante.

Alors... 

const Components = props => {
  return (
    <React.Fragment>

      <ComponentOne\>
      <ComponentTwo\>

    <\React.Fragment>
  )
}

export default Components

Cela vous permet de placer plusieurs composants les uns à côté des autres sans qu'un élément DOM les contient.

Vous devriez alors pouvoir le restituer en l’utilisant comme un composant normal et le restituera tous, alors importez-le ensuite ...

<Components \>

Sinon, si vous voulez les traiter comme un tableau, vous avez une fonction gratuite sur l’objet React que vous avez importé ...

React.Children.toArray(arrayOfComponents)

Vous lui transmettez un tableau de composants (comme dans votre question initiale) et cela vous permet de le trier et de le découper si vous en avez besoin. Vous devriez alors pouvoir le déposer dans le retour de votre fonction de rendu 

3
Matt Wills

C'est assez facile, encapsulez simplement votre composant dans div et transmettez-y key

const Example = ({components}) => (
  <div>
    {components.map((component, i) => <div key={i}>{component}</div>)}    
  </div>
)

Worked example

1
The Reason

Toutes ces réponses sont presque exactes. Supprimez simplement le <../> de vos exportations:

export default [ ComponentOne, ComponentTwo, ]

Et dans l'autre fichier, utilisez .map():

export default class Dashboard extends React.Component {
    render = () => (
        <div className="tile is-parent">
            {components.map((Component, key) => (<Component key={key} />))}
        </div>
    )
}

Notez également que si vous souhaitez utiliser Fragment comme les autres personnes suggérées, vous pouvez simplement écrire <>...</> à la place.

0
Dustin

En fait, vous exportez un tableau de elements à partir du fichier. Une façon est d'exporter un tableau de composants et de les rendre comme

import React from 'react';
export default [
    ComponentOne
    ComponentTwo
];
// Then following will work
{components.map((Component, key) => (
    // Remember to make first letter capital (in this case "c")
    <Component key={key}/>
}

L’autre façon est d’envelopper le composant dans div comme ceci

import React from 'react';
export default [
    <ComponentOne/>
    <ComponentTwo/>
];
// Then wrap in div
{components.map((component, key) => (
    <div key={key}>
      {component}
    </div>
}
0
Prakash Sharma

Suite à mon commentaire, vous devriez faire ceci à la place:

{components.map((component, index) => (
    <span key={index}>
        { component }
    </span>
}

Avec React 16, vous pouvez utiliser React.Fragment:

{components.map((component, index) => (
    <React.Fragment key={index}>
        { component }
    </React.Fragment>
}
0
John Kennedy