78 votes

Comment boucler et rendre des éléments dans React-native ?

Est-il possible de boucler un composant identique dans la fonction Render ?

Algo así:

...

onPress = () => {
 ...
};

initialArr = [["blue","text1"],["red","text2"]];
buttonsListArr = [];

for (let i = 0; i < initialArr.length; i++) 
{
 buttonsListArr.push(
   <Button style={{borderColor:{initialArr[i][0]}}} onPress={this.onPress.bind(this)}>{initialArr[i][1]}</Button>
 );
}

...

render() {
  return (
    <View style={...}>
     {buttonsListArr}
    </View>
)};

Je veux dire qu'il s'agit juste d'une liste finie de composants, donc tout composant comme ListView/ScrollView etc. n'est pas applicable dans ce cas particulier. C'est juste une question de syntaxe.

0 votes

Pourquoi ne pas utiliser map à la place ? const buttons = buttonsListArr.map( item => <Button style={{borderColor:item[0]}} onPress={this.onPress.bind(this)}>{item[1]}</Button> render() { return ( <View style={...}> <buttons /> </View> )};

71voto

nbkhope Points 3680

On utilise généralement une carte pour ce genre de choses.

buttonsListArr = initialArr.map(buttonInfo => (
  <Button ... key={buttonInfo[0]}>{buttonInfo[1]}</Button>
);

(la clé est un accessoire nécessaire chaque fois que l'on fait du mapping dans React. La clé doit être un identifiant unique pour le composant généré)

Par ailleurs, j'utiliserais un objet plutôt qu'un tableau. Je trouve que c'est plus joli :

initialArr = [
  {
    id: 1,
    color: "blue",
    text: "text1"
  },
  {
    id: 2,
    color: "red",
    text: "text2"
  },
];

buttonsListArr = initialArr.map(buttonInfo => (
  <Button ... key={buttonInfo.id}>{buttonInfo.text}</Button>
);

8 votes

Merci pour cette réponse. Pouvez-vous expliquer pourquoi map est utilisé ? J'ai essayé forEach et cela n'a pas fonctionné. Je ne comprends pas pourquoi je dois utiliser map.

6 votes

@AlexWang vous utilisez map parce que for each itère simplement à travers les éléments alors que map renvoie un tableau de la même taille, rempli avec les résultats de la fonction de mapping.

0 votes

Les rendus de type react sont basés sur retours , forEach ne renvoie rien (de l'intérieur) cependant, ce qui ne convient pas à la boucle de retour basée sur le retour :-) Cependant si vous ne voulez pas effectuer de rendu et simplement enregistrer des données/envoyer les données (en gros, tout ce qui n'est pas un retour), alors forEach((el, i) =>... serait plus logique d'un point de vue sémantique :)

55voto

Damathryx Points 105
render() {
  return (
    <View style={...}>
       {initialArr.map((prop, key) => {
         return (
           <Button style={{borderColor: prop[0]}}  key={key}>{prop[1]}</Button>
         );
      })}
     </View>
  )
}

devrait faire l'affaire

1 votes

Cela a l'air bien, mais je déplacerais le mappage avant l'instruction de retour pour rendre les choses plus agréables et j'utiliserais simplement le nom de la variable du tableau mappé à l'intérieur de la vue. A noter que le second paramètre de la fonction map est l'index de l'élément du tableau que vous parcourez. Bien qu'il puisse s'agir d'un entier différent à chaque fois, ce ne sont pas nécessairement de bons candidats pour la propriété key. Les éléments du tableau peuvent changer et la clé devra donc être modifiée également (si vous utilisez un identifiant unique, les clés resteront les mêmes même si les indices ont changé).

2 votes

Selon la documentation de React, "Nous ne recommandons pas l'utilisation d'index pour les clés si les éléments peuvent être réorganisés, car cela serait lent. " -- facebook.github.io/react/docs/listes-et-keys.html (Section des clés, en bas)

0 votes

@nbkhope c'est une nouvelle information pour moi à propos des clés. Merci de votre compréhension.

23voto

Nebojsa Zoric Points 41

Pour un tableau initial, il est préférable d'utiliser un objet plutôt qu'un tableau, car vous n'aurez alors plus à vous soucier des index et vous saurez beaucoup plus clairement ce qui est quoi :

const initialArr = [{
    color: "blue",
    text: "text1"
}, {
    color: "red",
    text: "text2"
}];

Pour le mappage réel, utilisez JS Array map au lieu de for loop - for loop devrait être utilisé dans les cas où il n'y a pas de tableau défini, comme afficher quelque chose un certain nombre de fois :

onPress = () => {
    ...
};

renderButtons() {
    return initialArr.map((item) => {
        return (
            <Button 
                style={{ borderColor: item.color }}
                onPress={this.onPress}
            >
                {item.text}
            </Button>
        );
    });
}

...

render() {
    return (
        <View style={...}>
            {
                this.renderButtons()
            }
        </View>
    )
}

J'ai déplacé le mappage dans une fonction séparée en dehors de la méthode de rendu pour un code plus lisible. Il y a beaucoup d'autres façons de boucler une liste d'éléments dans react native, et la façon que vous utiliserez dépendra de ce que vous avez besoin de faire. La plupart de ces méthodes sont couvertes dans cet article sur les boucles React JSX Bien qu'il utilise des exemples de React, tout ce qu'il contient peut être utilisé dans React Native. N'hésitez pas à y jeter un coup d'œil si vous êtes intéressé par ce sujet !

Par ailleurs, en dehors du sujet de la boucle, comme vous utilisez déjà la syntaxe du tableau pour définir la fonction onPress, il n'est pas nécessaire de la lier à nouveau. Encore une fois, cela ne s'applique que si la fonction est définie à l'aide de cette syntaxe dans le composant, car la syntaxe de la flèche lie automatiquement la fonction.

1 votes

Si quelqu'un a des difficultés à recréer cette réponse, rappelez-vous que <Button /> doit se fermer automatiquement (d'après ce que j'ai compris) et pour y afficher du texte, il faut passer par le prop (propriété ou attribut). title="" Pour en savoir plus sur le bouton, cliquez ici

0 votes

Pourquoi la fonction renderButtons a-t-elle 2 déclarations de retour ?

2voto

Tiago Pereira Points 21

Si vous voulez un départ direct/rapide, sans avoir à vous préoccuper des variables :

{
 urArray.map((prop, key) => {
     console.log(emp);
     return <Picker.Item label={emp.Name} value={emp.id} />;
 })
}

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