こんにちは、Habr!
私は時々インタビューをしますが、質問がReactキーに関するものである場合、ほとんどの場合、「はい、質問することは何もありませんか?」とほのめかす困惑した表情を目にします。Reactキーが明確でシンプルに思える場合は、ミニインタビューを実施しましょう(この記事はビデオのトランスクリプトです)
ウォームアップの問題
問題の定式化
3人のユーザーの配列があると想像してください。ユーザーの構造は可能な限り原始的で、フィールドは2つだけです。これは、id(一意の識別子)と2番目のフィールド名(実際のユーザー名)です。
const users = [{
id: 1,
name: 'Alexander',
}, {
id: 2,
name: 'Dmitriy',
}, {
id: 3,
name: 'Anton',
}];
これらのユーザーをレンダリングしてみましょう。このために、次のコードを使用します。
const Users = ({ users }) => {
return users.map((user) => {
return (
<User
key={user.id}
name={user.name}
/>
);
}
}
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>
);
}
}
ライフサイクルをより明確にするために、このコンポーネントをクラスで作成しました。そして、もう1つ注目したいのは、PureComponentです。これは、プロパティ(props)が変更された場合にのみコンポーネントが更新されることを意味します。
その結果、ブラウザに次のような画像が表示されます。
3つの名前のリストが表示され、コンソールには3つのエントリ、つまり各ユーザーのDIDMOUNTが表示されます。これまでのところ、すべてが論理的で予測可能です。
陰謀のタスクと質問
. , 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',
}];
また、役割に応じて、通常のユーザーの場合はUserコンポーネントが描画され、管理者の場合はAdminコンポーネントが描画されます。以下のために重要な、我々はまだ使用したインデックスを。
const Users = ({ users }) => {
return users.map((user) => {
const Component = user.role === 'admin' ? Admin : User;
return (
<Component
key={index}
name={user.name}
/>
);
}
}
そしてここでも、ユーザーDmitriyが削除されました。
この場合、コンソールにはどのログが表示されると思いますか?
私は答えを開示しません、私はそれを独立した研究のために残します...
結論
この記事には特に要約はありません。あなたが私のタスクを完了することに興味を持って興味を持っていて、おそらくあなた自身のために何か新しいものを発見したことを願っています、そしてあなたがそれをとても好きでもっと欲しいなら、リンクをたどってください