Do you know all about React key?

Hello, Habr!



I do interviews from time to time, and when the question is about the React key , most often I see a perplexed look, hinting, "Yes, there is nothing to ask?". If React key seems clear and simple to you, then let's conduct a mini interview ( this article is a transcript of the video )



Warm-up problem



Formulation of the problem



Imagine we have an array of three users. The structure of the user is as primitive as possible, there are only 2 fields, this is id - a unique identifier and the second field name - the actual username.



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


Let's try to render these users, for this we use the following code:



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


Let's take a look at what the User component is .



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>
    );
  }
}


I wrote this component in classes for better clarity of the life cycle. And one more point to which I would like to draw your attention is PureComponent . This means that the component will be updated only if the properties (props) are changed.



As a result, in the browser we will see something like the following picture:







We see a list of three names, and in the console we see three entries, namely DID MOUNT for each user. So far, everything is logical and predictable.



Intrigue task and question



. , 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',
}];


And depending on the role, if it is a regular user, the User component is drawn, and if it is an administrator, then the Admin component . For key, we still use index .



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

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


And here again the user Dmitriy was deleted .



What do you think in this case what logs will be in the console?



I will not disclose the answer, I will leave it for independent study ...



Conclusion



There is no particular summary in this article. I hope you were just interested and curious to complete my tasks and maybe you discovered something new for yourself, and if you liked it so much and you want more, follow the link




All Articles