Savez-vous tout sur la clé React?

Bonjour, Habr!



Je fais des interviews de temps en temps, et quand la question porte sur la touche React , le plus souvent je vois un regard perplexe, laissant entendre: "Oui, il n'y a rien à demander?". Si la touche React vous semble claire et simple, alors menons une mini-interview ( cet article est une transcription de la vidéo )



Problème d'échauffement



Formulation du problème



Imaginez que nous ayons un tableau de trois utilisateurs. La structure de l'utilisateur est aussi primitive que possible, il n'y a que 2 champs, c'est id - un identifiant unique et le deuxième nom de champ - le nom d'utilisateur réel.



const users = [{
  id: 1,
  name: 'Alexander',
}, {
  id: 2,
  name: 'Dmitriy',
}, {
  id: 3,
  name: 'Anton',
}];


Essayons de rendre ces utilisateurs, pour cela nous utilisons le code suivant:



const Users = ({ users }) => {
  return users.map((user) => {
    return (
      <User
        key={user.id}
        name={user.name}
      />
    );
  }
}


Jetons un coup d'œil à ce qu'est le composant User .



class User extends PureComponent {
  componentDidMount() {
    console.log("DID MOUNT  ", this.props.name);
  }
  componentDidUpdate(prevProps) {
    console.log("DID UPDATE  ", prevProps.name, " -> ", this.props.name);
  }
  componentWillUnmount() {
    console.log("WILL UNMOUNT  ", this.props.name);
  }
  render() {
    return (
      <span>{this.props.name}</span>
    );
  }
}


J'ai écrit ce composant en classe pour une meilleure clarté du cycle de vie. Et un autre point sur lequel je voudrais attirer votre attention est PureComponent . Cela signifie que le composant ne sera mis à jour que si les propriétés (accessoires) sont modifiées.



En conséquence, dans le navigateur, nous verrons quelque chose comme l'image suivante:







Nous voyons une liste de trois noms, et dans la console, nous voyons trois entrées, à savoir DID MOUNT pour chaque utilisateur. Jusqu'à présent, tout est logique et prévisible.



Tâche et question d'intrigue



. , id, .



const users = [{
  id: 1,
  name: 'Maxim', // 'Alexander',
}, {
  id: 4, // 2,
  name: 'Dmitriy',
}, {
  id: 3,
  name: 'Anton',
}];


!

?







, ...















!



, . :







, Alexander Maxim, Dmitriy Anton, . :



  1. WILL UNMOUNT Dmitriy
  2. DID UPDATE Alexander Maxim
  3. Dmitriy .


, ? ,





,



Anton, key name , key name , User PureComponent. .







Alexander name Maxim, props , componentDidUpdate. , .







Dmitriy, User PureComponent name, - . Dmitriy Dmitriy . WILL UNMOUN DID MOUNT.







React key. , key , key , , key, . , key , key , . , Dmitriy , ,





, !





React . index . , eslint , index key. .



, , React :







, .





, 5 .



const users = [{
  id: 1,
  name: 'Alexander',
}, {
  id: 2,
  name: 'Dmitriy',
}, {
  id: 3,
  name: 'Anton',
}, {
  id: 4,
  name: 'Artem',
}, {
  id: 5,
  name: 'Andrey',
}];


key idindex



const Users = ({ users }) => {
  return users.map((user) => {
    return (
      <User
        key={index}
        name={user.name}
      />
    );
  }
}


User .



5 DID MOUNT . , Dmitriy .



const users = [{
  id: 1,
  name: 'Alexander',
}/*, {
  id: 2,
  name: 'Dmitriy',
}*/, {
  id: 3,
  name: 'Anton',
}, {
  id: 4,
  name: 'Artem',
}, {
  id: 5,
  name: 'Andrey',
}];




, ?





.













!









WILL UNMOUNT Andrey, , Dmitriy, Andrey. 3 , . DID UPDATE .





, . 5 . , .. Dmitriy. , , .







, React. 5 , key. 4 . key. react, key, , .







.







, . , Dmitriy, props name Anton. DID UPDATE. , 3 DID UPDATE. key 5, , WILL UNMOUNT Andrey, WILL UNMOUNT Dmitriy.





id, index key. , Dmitriy, . React . , , , drag and drop, .





, :



const users = [{
  id: 1,
  name: 'Alexander',
  role: 'user',
}, {
  id: 2,
  name: 'Dmitriy',
  role: 'admin',
}, {
  id: 3,
  name: 'Anton',
  role: 'user',
}, {
  id: 4,
  name: 'Artem',
  role: 'admin',
}, {
  id: 5,
  name: 'Andrey',
  role: 'user',
}];


Et selon le rôle, s'il s'agit d'un utilisateur normal, le composant Utilisateur est dessiné, et s'il s'agit d'un administrateur, le composant Admin . Pour la clé, nous utilisons toujours index .



const Users = ({ users }) => {
  return users.map((user) => {
    const Component = user.role === 'admin' ? Admin : User;

    return (
      <Component
        key={index}
        name={user.name}
      />
    );
  }
}


Et là encore, l'utilisateur Dmitriy a été supprimé .



Que pensez-vous dans ce cas quels journaux seront dans la console?



Je ne divulguerai pas la réponse, je la laisserai pour une étude indépendante ...



Conclusion



Il n'y a pas de résumé particulier dans cet article. J'espère que vous étiez simplement intéressé et curieux de terminer mes tâches et peut-être avez-vous découvert quelque chose de nouveau pour vous-même, et si vous l'avez tellement aimé et que vous en voulez plus, suivez le lien




All Articles