Olá, Habr!
De vez em quando dou entrevistas e quando a pergunta é sobre a chave React , na maioria das vezes vejo um olhar perplexo, que sugere: "Sim, não há nada a perguntar?" Se a chave React parece clara e simples para você, então vamos realizar uma mini entrevista ( este artigo é uma transcrição do vídeo )
Problema de aquecimento
Formulação do problema
Imagine que temos uma matriz de três usuários. A estrutura do usuário é a mais primitiva possível, existem apenas 2 campos, este é id - um identificador único e o segundo nome de campo - o nome de usuário real.
const users = [{
id: 1,
name: 'Alexander',
}, {
id: 2,
name: 'Dmitriy',
}, {
id: 3,
name: 'Anton',
}];
Vamos tentar renderizar esses usuários, para isso usamos o seguinte código:
const Users = ({ users }) => {
return users.map((user) => {
return (
<User
key={user.id}
name={user.name}
/>
);
}
}
Vamos dar uma olhada no que é o componente 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>
);
}
}
Escrevi este componente em aulas para melhor clareza do ciclo de vida. E mais um ponto para o qual gostaria de chamar a atenção é o PureComponent . Isso significa que o componente será atualizado apenas se as propriedades (props) forem alteradas.
Como resultado, veremos no navegador algo como a seguinte imagem:

Vemos uma lista de três nomes e, no console, três entradas, a saber, DID MOUNT para cada usuário. Até agora, tudo é lógico e previsível.
Tarefa e pergunta de intriga
. , id, .
const users = [{
id: 1,
name: 'Maxim', // 'Alexander',
}, {
id: 4, // 2,
name: 'Dmitriy',
}, {
id: 3,
name: 'Anton',
}];
!
?
, ...
!
, . :

, Alexander Maxim, Dmitriy Anton, . :
- WILL UNMOUNT Dmitriy
- DID UPDATE Alexander Maxim
- 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 id — index
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',
}];
E dependendo da função, se for um usuário regular, o componente Usuário é desenhado, e se for um administrador, o componente Admin . Para a chave, ainda usamos o índice .
const Users = ({ users }) => {
return users.map((user) => {
const Component = user.role === 'admin' ? Admin : User;
return (
<Component
key={index}
name={user.name}
/>
);
}
}
E aqui novamente o usuário Dmitriy foi excluído .
O que você acha nesse caso, quais logs estarão no console?
Não vou divulgar a resposta, vou deixar para estudo independente ...
Conclusão
Não há um resumo específico neste artigo. Espero que você esteja apenas interessado e curioso para completar minhas tarefas e talvez você tenha descoberto algo novo para si mesmo, e se gostou tanto e quer mais, siga o link