Je viens de commencer avec ReactJS et j'ai essayé des solutions à d'autres questions similaires à celle-ci mais pas de chance jusqu'à présent.

Voici mon code de travail:

import React from 'react';
import ReactDOM from 'react-dom';


const Numbers = ['2', '4', '6', '8'];

const NumbersList = (props) => (
   <ul>
      {
          props.Numbers.map (
             number => <li key={number}>{number * 2}</li>
          )
      }
    </ul>
)
ReactDOM.render(<NumbersList Numbers = {Numbers} />, document.getElementById('root') )

Mais quand je passe Numbers Array comme:

const Numbers = ['4', '4', '6', '8']

Je reçois cette erreur:

Avertissement: deux enfants rencontrés avec la même clé, 4. Les clés doivent être uniques pour que les composants conservent leur identité dans toutes les mises à jour.

Ma question est donc la suivante: quelle est la meilleure façon de donner des clés dans cette situation? Et si j'utilise Number (comme dans l'exemple ci-dessus) comme clés, quelle est la meilleure solution pour éviter cet avertissement?

Merci!

8
Ankit Pandey 15 avril 2018 à 13:50

6 réponses

Meilleure réponse

Lorsque vous n'avez pas de propriété unique définitive pour les éléments (une liste de primitives non uniques), vous pouvez utiliser l'index.

Remarque: n'utilisez pas l'index si les éléments ont un id unique (et une liste non primitive devrait), car il s'agit d'un support anti-pattern.

const Numbers = ['2', '4', '4', '8'];

const NumbersList = (props) => (
  <ul>
  {
  props.Numbers.map (
    (number, index) => <li key={index}>{number * 2}</li>
  )}
  </ul>
)

ReactDOM.render(
  <NumbersList Numbers = {Numbers} />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
10
Ori Drori 15 avril 2018 à 11:39

React s'attend à ce que les éléments répétés (frères et sœurs) aient une propriété de clé afin de pouvoir distinguer les éléments sur les rendus suivants. Cela lui permet d'optimiser le rendu du graphique des éléments à mesure que les éléments vont, viennent et changent.

key est censé être une chaîne, mais React contraindra un nombre à la chaîne pour vous. Votre exemple est assez simpliste, il est plus normal que les données contiennent une valeur d'élément unique (comme l'ID d'enregistrement de base de données) afin que les propriétés en double puissent être prises en charge tout en permettant de distinguer les éléments. En l'absence d'une propriété id externe, vous pouvez décider d'ajouter un identifiant unique dans le cadre de l'état.

Il est possible d'utiliser l'index des éléments dans la liste, mais cela ne permettra pas toujours à React d'optimiser le cycle de rendu des éléments. C'est pourquoi il est déconseillé si vos données contiennent un identifiant d'article unique.

React vérifie les clés en double et manquantes pour éviter les erreurs les plus évidentes qui pourraient rendre le cycle de rendu moins efficace.

L'optimisation du rendu Reacts fera vraiment la différence dans les très longues listes. Pour une application où la portée ne sera probablement que de quelques éléments, il n'y aura pas beaucoup de gain, et donc l'index de tableau pourrait être une solution raisonnable.

0
Dave Meehan 15 avril 2018 à 11:08

La raison en est que chaque balise <li> doit avoir une clé unique. Vous affectez key=4 dans votre balise <li> car l'élément 4 est en double dans votre tableau.

Après modification

Mon mauvais, je n'ai pas lu toute la question. utilisez le package uuid pour générer un nouvel identifiant: https://www.npmjs.com/package/uuid Ils ont également de la documentation.

2
DadyByte 15 avril 2018 à 10:59

Utiliser le index comme key est un anti-modèle et conduit toujours à des bugs dans n'importe quelle situation.

Pour la meilleure réponse - que se passerait-il si quelqu'un changeait le nombre derrière l'index 1 en, par exemple, 5? Le nombre affiché restera le même, car le key n'a pas été modifié .

Pour contourner les problèmes causés par l'utilisation de index en tant que key pour les primitives, je recommande d'utiliser des clés composites .

J'écrirais le composant NumbersList de la façon suivante:

const NumbersList = ({ numbers }) => ( <ul> {numbers.map((number, index) => ( <li key={`${index}:${number}`}>{number * 2}</li> )} </ul> );

0
Bohdan Shulha 15 avril 2018 à 11:58

Faites-y ajouter une clé unique ainsi que des données personnalisées

import React from 'react';
import ReactDOM from 'react-dom';


const Numbers = ['2', '4', '6', '8'];

const NumbersList = (props) => (
   <ul>
      {
          props.Numbers.map (
             (number, i) => <li key={i} custom={number}>{number * 2}</li>
          )
      }
    </ul>
)
ReactDOM.render(<NumbersList Numbers = {Numbers} />, document.getElementById('root') )

L'accessoire clé doit être unique, j'ai donc donné la valeur renvoyée par la méthode map, l'attribut personnalisé sera les données du tableau que vous souhaitez définir pour tous les éléments.

1
Rajendran Nadar 15 avril 2018 à 11:12

React utilise keys pour identifier les éléments qui ont été modifiés, ajoutés ou supprimés.

La meilleure façon de choisir un key est d'utiliser une chaîne qui identifie de manière unique un élément de liste parmi ses frères et sœurs. Le plus souvent, vous utiliseriez des identifiants de vos données comme clés.

Il n'est pas recommandé d'utiliser les index de tableau comme clé car vous pouvez mettre à jour / supprimer l'élément d'un tableau mais les index resteront les mêmes, donc React ne pourra pas identifier la modification et affichera les mauvais résultats.

Dans votre code, vous n'avez pas d'identifiant unique pour les éléments de tableau, donc la seule chose que vous pouvez utiliser pour le rendre unique est les index de tableau.

const Numbers = ['2', '4', '4', '8'];

const NumbersList = (props) => (
  <ul>
  {
  props.Numbers.map (
    (number, index) => <li key={index}>{number * 2}</li>
  )}
  </ul>
)

ReactDOM.render(
  <NumbersList Numbers = {Numbers} />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
-1
Ankit Chaurasia 5 déc. 2018 à 17:33