web-dev-qa-db-fra.com

Compréhension des clés uniques pour les enfants de tableau dans React.js

Je construis un composant React qui accepte une source de données JSON et crée un tableau pouvant être trié.
Chacune des lignes de données dynamiques a une clé unique, mais je reçois toujours une erreur de: 

Chaque enfant dans un tableau doit avoir un accessoire "clé" unique.
Vérifiez la méthode de rendu de TableComponent.

Ma méthode de rendu TableComponent renvoie:

<table>
  <thead key="thead">
    <TableHeader columns={columnNames}/>
  </thead>
  <tbody key="tbody">
    { rows }
  </tbody>
</table>

Le composant TableHeader est constitué d'une seule ligne et est également associé à une clé unique.

Chaque row dans rows est construite à partir d'un composant avec une clé unique:

<TableRowItem key={item.id} data={item} columns={columnNames}/>

Et la 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 d'accessoire clé unique? 

404
Brett DeWoody

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, chaque <TableRowItem key={item.id} data={item} columns={columnNames}/> tente de rendre certains enfants à l'intérieur sans clé.

Vérifiez cet exemple .

Essayez de supprimer le key={i} de l'élément <b></b> à l'intérieur du div (et vérifiez la console).

Dans l'exemple, si nous ne donnons pas de clé à l'élément <b> et si nous voulons mettre à jour uniquement le object.city, React doit restituer la ligne entière par rapport à l'élément. 

Voici le code:

var data = [{name:'Jhon', age:28, city:'HO'},
            {name:'Onhj', age:82, city:'HN'},
            {name:'Nohj', age:41, city:'IT'}
           ];

var Hello = React.createClass({

    render: function() {

      var _data = this.props.info;
      console.log(_data);
      return(
        <div>
            {_data.map(function(object, i){
               return <div className={"row"} key={i}> 
                          {[ object.name ,
                             // remove the key
                             <b className="fosfo" key={i}> {object.city} </b> , 
                             object.age
                          ]}
                      </div>; 
             })}
        </div>
       );
    }
});

React.render(<Hello info={data} />, document.body);

La réponse postée par @Chris en bas est beaucoup plus détaillée que cette réponse. S'il vous plaît jetez un oeil à https://stackoverflow.com/a/43892905/2325522

Réagissez la documentation sur l'importance des clés dans la réconciliation: Clés

402
jmingov

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 de tableau sur lesquels nous allons parcourir, une ressemblance unique est nécessaire.

React gère le rendu des composants itératif sous forme de tableaux.

Un meilleur moyen de résoudre ce problème est de fournir un index sur les éléments du tableau sur lesquels vous allez parcourir. 

class UsersState extends Component
    {
        state = {
            users: [
                {name:"shashank", age:20},
                {name:"vardan", age:30},
                {name:"somya", age:40}
            ]
        }
    render()
        {
            return(
                    <div>
                        {
                            this.state.users.map((user, index)=>{
                                return <UserState key={index} age={user.age}>{user.name}</UserState>
                            })
                        }
                    </div>
                )
        }

index est les accessoires intégrés de React.

2
Shashank Malviya

Ajoutez simplement la clé unique à vos composants 

data.map((marker)=>{
    return(
        <YourComponents 
            key={data.id}     // <----- unique key
        />
    );
})
1
Mahdi Bashirpour

J'ai corrigé ceci en utilisant Guid pour chaque touche comme ceci: Génération de Guid:

guid() {
    return this.s4() + this.s4() + '-' + this.s4() + '-' + this.s4() + '-' +
        this.s4() + '-' + this.s4() + this.s4() + this.s4();
}

s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
}

Et puis assigner cette valeur aux marqueurs:

{this.state.markers.map(marker => (
              <MapView.Marker
                  key={this.guid()}
                  coordinate={marker.coordinates}
                  title={marker.title}
              />
          ))}
1
Archil Labadze

Vérifier: clé = undef !!!

Vous avez aussi le message d'avertissement:

Each child in a list should have a unique "key" prop.

si votre code est complet à droite, mais si activé

<ObjectRow key={someValue} />

une valeur n'est pas définie !!! Veuillez vérifier ceci en premier. Vous pouvez économiser des heures.

0
Gerd

La solution la plus simple que j'ai trouvée consiste à créer un identifiant unique pour chaque élément de la liste. Il y a 2 bibliothèques, uniqid et uuid.

npm install uniqid

Puis dans votre code:

import uniqueid from 'uniqid'
- OR if you use require:   var uniqid = require('uniqid');

Ensuite, ajoutez simplement une clé à l'élément HTML qui en a besoin. Dans l'exemple ci-dessous, notez que la clé = {uniqueid ()}

{this.state.someList.map((item) => <li>{item}</li>)}
I changed to this:
{this.state.someList.map((item) => <li key={uniqueid()}>{item}</li>)}
0
MattC