zishu's blog

zishu's blog

一个热爱生活的博主。https://zishu.me

なぜキーは必要なのですか?

以前にも述べたように、React ではリストをレンダリングする際に、各データにキー値を付ける必要があります。キー値は一意の識別子を与えるものであり、どのように識別子を付けるかについても詳しく説明しました。では、なぜこれを行う必要があるのでしょうか?

React でリストをレンダリングする方法

デフォルトの条件では、再帰的に DOM ノードの子要素を処理する際、React は 2 つの子要素のリストを同時に走査します。差異が生じた場合、変更を生成します。

要素リストの末尾に要素を追加する場合、更新コストは比較的小さくなります。例えば:

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

React は最初に 2 つの<li>first</li>に対応するツリーをマッチさせ、次に 2 番目の要素<li>second</li>に対応するツリーをマッチさせ、最後に 3 番目の要素<li>third</li>のツリーを挿入します。

ただし、要素を単純に先頭に追加するだけでは、更新コストが大きくなります。例えば:

<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

React は<li>Duke</li><li>Villanova</li>を保持すべきであることに気づかず、各子要素を再構築します。この場合、パフォーマンスの問題が発生します。

キー

上記の問題を解決するために、React はkey属性をサポートしています。子要素にキーがある場合、React はキーを使用して元のツリー上の子要素と最新のツリー上の子要素をマッチさせます。以下の例では、keyを追加することで以前の非効率な変換を効率的にします:

<ul>
  <li key="1">Duke</li>
  <li key="2">Villanova</li>
</ul>

<ul>
  <li key="0">Connecticut</li>
  <li key="1">Duke</li>
  <li key="2">Villanova</li>
</ul>

これにより、React は'0'キーを持つ要素だけが新しい要素であり、'1'および'2'キーを持つ要素は移動したことがわかります。

実際のシナリオでは、キーを生成することは困難ではありません。表示する要素にはすでに一意の ID があるかもしれないため、キーは直接データから抽出することができます:

<li key={item.id}>{item.name}</li>

これが成立しない場合は、モデルに ID フィールドを追加するか、一部のコンテンツをハッシュ値として使用してキーを生成することができます。このキーはグローバルに一意である必要はありませんが、リスト内では一意である必要があります。

最後に、配列内の要素のインデックスをキーとして使用することもできます。この戦略は要素の並べ替えが行われない場合に適しており、順序が変更されると diff が遅くなります。

インデックスベースのコンポーネントを再ソートする場合、コンポーネントの状態に問題が発生する可能性があります。コンポーネントインスタンスは、そのキーに基づいて更新と再利用が行われるため、キーがインデックスである場合、順序を変更すると現在のキーが変更され、予期しない変更が発生する可能性があります(例:入力フィールドなどの非制御コンポーネント)。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。