Je construis un composant React qui accepte une source de données JSON et crée une table triable.
Chacune des lignes de données dynamiques a une clé unique qui lui est affectée mais je reçois toujours une erreur de:
Chaque enfant d'un tableau doit avoir un accessoire "clé" unique.
Vérifiez la méthode de rendu de TableComponent.
Ma TableComponent
méthode de rendu renvoie:
<table>
<thead key="thead">
<TableHeader columns={columnNames}/>
</thead>
<tbody key="tbody">
{ rows }
</tbody>
</table>
Le TableHeader
composant est une seule ligne et une clé unique lui est également attribuée.
Chaque row
en rows
est construit à partir d' un composant avec une clé unique:
<TableRowItem key={item.id} data={item} columns={columnNames}/>
Et le TableRowItem
ressemble à ceci:
var TableRowItem = React.createClass({
render: function() {
var td = function() {
return this.props.columns.map(function(c) {
return <td key={this.props.data[c]}>{this.props.data[c]}</td>;
}, this);
}.bind(this);
return (
<tr>{ td(this.props.item) }</tr>
)
}
});
Quelle est la cause de l'erreur unique d'accessoire de clé?
javascript
reactjs
Brett DeWoody
la source
la source
key
propriété unique . Cela aidera ReactJS à trouver des références aux nœuds DOM appropriés et à mettre à jour uniquement le contenu à l'intérieur du balisage, mais pas à restituer la table / ligne entière.rows
tableau ou plus préférablement un jsfiddle? Vous n'avez pas besoin d'unekey
propriété surthead
ettbody
d'ailleurs.Réponses:
Vous devez ajouter une clé à chaque enfant ainsi qu'à chaque élément à l'intérieur des enfants .
De cette façon, React peut gérer le changement minimal de DOM.
Dans votre code, chacun
<TableRowItem key={item.id} data={item} columns={columnNames}/>
essaie de rendre certains enfants à l'intérieur d'eux sans clé.Vérifiez cet exemple .
Essayez de retirer le
key={i}
de l'<b></b>
élément à l' intérieur du div (et de vérifier la console).Dans l'exemple, si nous ne donnons pas de clé à l'
<b>
élément et que nous voulons mettre à jour uniquement leobject.city
, React doit restituer la ligne entière par rapport à l'élément uniquement.Voici le code:
La réponse postée par @Chris en bas est beaucoup plus détaillée que cette réponse. Veuillez consulter https://stackoverflow.com/a/43892905/2325522
Réagissez à la documentation sur l'importance des clés dans la réconciliation: Clés
la source
key
valeur de l'accessoire est unique pour chaque élément et que vous placez l'key
accessoire sur le composant le plus proche des limites du tableau. Par exemple, dans React Native, j'essayais d'abord de mettrekey
prop au<Text>
composant. Cependant, je devais le mettre au<View>
composant qui est parent de<Text>
. si Array == [(Affichage> Texte), (Affichage> Texte)] vous devez le mettre en Affichage. Pas de texte.Soyez prudent lors de l'itération sur les tableaux !!
Il est faux de penser que l'utilisation de l'index de l'élément dans le tableau est un moyen acceptable de supprimer l'erreur que vous connaissez probablement:
Cependant, dans de nombreux cas, ce n'est pas le cas! Il s'agit d'un anti-modèle qui peut dans certaines situations conduire à un comportement indésirable .
Comprendre l'
key
héliceReact utilise l'
key
hélice pour comprendre la relation élément-élément DOM, qui est ensuite utilisée pour le processus de réconciliation . Il est donc très important que la clé reste toujours unique , sinon il y a de fortes chances que React mélange les éléments et mute le mauvais. Il est également important que ces touches restent statiques tout au long de tous les rendus afin de maintenir les meilleures performances.Cela étant dit, il n'est pas toujours nécessaire d'appliquer ce qui précède, à condition que l'on sache que le tableau est complètement statique. Cependant, l'application des meilleures pratiques est encouragée dans la mesure du possible.
Un développeur React a déclaré dans ce numéro GitHub :
En bref, un
key
devrait être:Utilisation de l'
key
héliceSelon l'explication ci-dessus, étudiez attentivement les exemples suivants et essayez de mettre en œuvre, si possible, l'approche recommandée.
Mauvais (potentiellement)
C'est sans doute l'erreur la plus courante lors de l'itération sur un tableau dans React. Cette approche n'est pas techniquement "mauvaise" , c'est juste ... "dangereuse" si vous ne savez pas ce que vous faites. Si vous parcourez un tableau statique, c'est une approche parfaitement valide (par exemple un tableau de liens dans votre menu de navigation). Cependant, si vous ajoutez, supprimez, réorganisez ou filtrez des éléments, vous devez être prudent. Jetez un œil à cette explication détaillée dans la documentation officielle.
Afficher l'extrait de code
Dans cet extrait, nous utilisons un tableau non statique et nous ne nous limitons pas à l'utiliser comme une pile. Il s'agit d'une approche dangereuse (vous comprendrez pourquoi). Notez que lorsque nous ajoutons des éléments au début du tableau (essentiellement non décalés), la valeur de chacun
<input>
reste en place. Pourquoi? Parce que lekey
n'identifie pas chaque élément de manière unique.En d' autres termes, tout d' abord
Item 1
akey={0}
. Lorsque nous ajoutons le deuxième élément, l'élément supérieur devientItem 2
, suiviItem 1
du deuxième élément. Cependant, maintenantItem 1
akey={1}
et nonkey={0}
plus. Au lieu de cela, aItem 2
maintenantkey={0}
!!En tant que tel, React pense que les
<input>
éléments n'ont pas changé, car laItem
touche avec0
est toujours en haut!Alors pourquoi cette approche n'est- elle que parfois mauvaise?
Cette approche n'est risquée que si le tableau est en quelque sorte filtré, réorganisé ou si des éléments sont ajoutés / supprimés. S'il est toujours statique, il est parfaitement sûr à utiliser. Par exemple, un menu de navigation comme
["Home", "Products", "Contact us"]
peut être itéré en toute sécurité avec cette méthode, car vous n'aurez probablement jamais ajouter de nouveaux liens ou les réorganiser.En bref, voici quand vous pouvez utiliser en toute sécurité l'index en tant que
key
:Si, à la place, dans l'extrait ci-dessus, nous avions poussé l'élément ajouté à la fin du tableau, l'ordre de chaque élément existant serait toujours correct.
Très mauvais
Bien que cette approche garantisse probablement l'unicité des clés, elle obligera toujours à réagir pour restituer chaque élément de la liste, même lorsque cela n'est pas nécessaire. C'est une très mauvaise solution car elle a un impact considérable sur les performances. Sans oublier que l'on ne peut pas exclure la possibilité d'une collision de clés dans le cas où
Math.random()
le même numéro serait produit deux fois.très bien
C'est sans doute la meilleure approche car elle utilise une propriété unique pour chaque élément de l'ensemble de données. Par exemple, si
rows
contient des données extraites d'une base de données, on pourrait utiliser la clé primaire de la table ( qui est généralement un numéro à incrémentation automatique ).Bien
C'est aussi une bonne approche. Si votre jeu de données ne contient aucune donnée garantissant l'unicité ( par exemple un tableau de nombres arbitraires ), il y a un risque de collision de clés. Dans de tels cas, il est préférable de générer manuellement un identifiant unique pour chaque élément de l'ensemble de données avant d'itérer dessus. De préférence lors du montage du composant ou lors de la réception de l'ensemble de données ( par exemple depuis
props
ou depuis un appel d'API asynchrone ), afin de le faire une seule fois , et non à chaque fois que le composant effectue un nouveau rendu. Il existe déjà une poignée de bibliothèques qui peuvent vous fournir de telles clés. Voici un exemple: react-key-index .la source
toString()
pour convertir en chaîne au lieu de laisser comme nombre. Est-ce important à retenir?key
. Je ne sais pas pourquoi ils le convertissent.key
finit toujours par être une chaîne de toute façon.Cela peut ou non aider quelqu'un, mais cela peut être une référence rapide. Ceci est également similaire à toutes les réponses présentées ci-dessus.
J'ai beaucoup d'emplacements qui génèrent une liste en utilisant la structure ci-dessous:
Après quelques essais et erreurs (et quelques frustrations), l'ajout d'une propriété de clé au bloc le plus externe l'a résolu. Notez également que la balise <> est maintenant remplacée par la balise maintenant.
Bien sûr, j'ai utilisé naïvement l'index d'itération (index) pour remplir la valeur de clé dans l'exemple ci-dessus. Idéalement, vous utiliseriez quelque chose qui est unique à l'élément de liste.
la source
Avertissement: chaque enfant d'un tableau ou d'un itérateur doit avoir un accessoire "clé" unique.
Ceci est un avertissement car pour les éléments du tableau sur lesquels nous allons répéter, il faudra une ressemblance unique.
React gère l'itération du rendu des composants sous forme de tableaux.
La meilleure façon de résoudre ce problème est de fournir un index sur les éléments du tableau sur lesquels vous allez effectuer une itération. Par exemple:
index est les accessoires intégrés de React.
la source
Ajoutez simplement la clé unique à vos composants
la source
Vérifiez: key = undef !!!
Vous avez également le message d'avertissement:
si votre code est complet à droite, mais s'il est activé
someValue n'est pas défini !!! Veuillez d'abord vérifier cela. Vous pouvez gagner des heures.
la source
Meilleure solution de définir une clé unique dans react: à l'intérieur de la carte, vous avez initialisé le nom post puis key define par key = {post.id} ou dans mon code vous voyez je définis le nom item puis je définis key par key = {item.id }:
la source
Ceci est un avertissement, mais le traitement de ce problème rendra Reacts plus rapide ,
En effet, il
React
doit identifier de manière unique chaque élément de la liste. Disons que si l'état d'un élément de cette liste change dans Reacts,Virtual DOM
alors React doit déterminer quel élément a été modifié et où dans le DOM il doit changer pour que le DOM du navigateur soit synchronisé avec le DOM virtuel Reacts.Comme solution, introduisez simplement un
key
attribut à chaqueli
balise. Celakey
devrait être une valeur unique pour chaque élément.la source
key
accessoire. Si vous n'en fournissez pas, React en attribuera un automatiquement (l'index actuel de l'itération).key={i}
. Cela dépend donc des données que contient votre tableau. Par exemple, si vous avez la liste["Volvo", "Tesla"]
, alors évidemment, la Volvo est identifiée par la clé0
et la Tesla avec1
- car c'est l'ordre dans lequel ils apparaîtront dans la boucle. Maintenant, si vous réorganisez le tableau, les clés sont échangées. Pour React, puisque "objet"0
est toujours en haut, il interprètera plutôt ce changement comme un "renommage", plutôt que comme une réorganisation. Les touches correctes ici auraient besoin d'être, dans l' ordre,1
alors0
. Vous ne réorganisez pas toujours en cours d'exécution, mais lorsque vous le faites, c'est un risque.Cela va aggraver le problème.
la source
J'étais en cours d'exécution dans ce message d'erreur en raison d'
<></>
être retourné pour certains éléments du tableau alors qu'ilnull
doit être renvoyé.la source
J'ai corrigé cela en utilisant Guid pour chaque clé comme ceci: Génération de Guid:
Et puis attribuer cette valeur aux marqueurs:
la source
Fondamentalement, vous ne devez pas utiliser l'index du tableau comme clé unique. Vous pouvez plutôt utiliser un
setTimeout(() => Date.now(),0)
pour définir la clé unique ou l' uuid unique ou toute autre manière qui générera un identifiant unique mais pas l'index du tableau comme identifiant unique.la source