44 votes

Rendu React d'un tableau de composants

Question rapide. Quelqu'un sait-il comment rendre un tableau de composants ? J'essaie de faciliter la tâche d'un développeur qui souhaite modifier un composant particulier. (C'est comme un tableau de bord).

Fichier de la liste des composants

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

Composant du 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 que j'ai un tableau de composants auquel je dois ajouter une clé. Cependant ! Je n'arrive pas à ajouter une clé au composant. Je ne sais pas comment l'expliquer, alors voici le code que j'ai essayé :

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

Si je fais ce qui précède, je n'obtiens pas d'erreur 'vous devez appliquer une clé', mais rien ne s'affiche ? Je suppose que c'est parce que le "composant" n'existe pas ou quelque chose de bizarre de ce genre.

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

Je suppose que ma solution de rechange est de renvoyer une fonction raccourcie au lieu d'un tableau, mais je préfère le tableau pour une raison quelconque ? Il semble plus simple pour les juniors.

21voto

Simon Boudrias Points 12696

Avez-vous envisagé d'utiliser le nouveau Fragments de React ? (au v16)

Ce serait la solution la plus simple, car elle permettrait de contourner le problème des tableaux et des clés.

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

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

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

15voto

Matt Wills Points 160

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

La meilleure pratique est de l'exporter comme une simple fonction qui renvoie les composants plutôt que comme une 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 ne les contienne.

Vous devriez ensuite être en mesure d'effectuer le rendu en l'utilisant comme un composant normal et il les rendra tous, il suffit donc de l'importer...

<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 passez un tableau de composants (comme dans votre question initiale) et il vous permet de le trier et de le découper si nécessaire, puis vous devriez être en mesure de le déposer dans le retour de votre fonction de rendu.

9voto

John Kennedy Points 2490

Pour faire suite à mon commentaire, vous devriez plutôt faire ceci :

{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>
}

4voto

Dustin Points 196

Toutes ces réponses sont presque correctes. Il suffit d'enlever 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 vouliez utiliser Fragment comme d'autres l'ont suggéré, vous pouvez simplement écrire <>...</> à la place.

1voto

Prakash Sharma Points 6829

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

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 moyen est d'envelopper le composant dans un fichier div comme ceci

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X