React におけるキーの役割を理解するには、まずキーの値から始めます。キーの値は、不定値、インデックス値、明確で一意の値の 3 種類に分けられます。 次のコードでは、キーの値は不定値です(Math.random()) 質問: ボタンをクリックすると、スパンの色が赤に変わりますか?React をインポートし、{useState} を 'react' から取得します。 関数App() { 定数[initMap、setInitMap] = useState([1,2,3,4]); const ハンドルクリック = () => { setInitMap([1,2,3,4]) var spanEle = document.getElementsByTagName('span'); Array.from(spanEle).map(it => it.style.color = 'red') } 戻る ( <div className="アプリ" id="アプリ"> { initMap.map((it,index) => <div key={Math.random()}><span>色</span></div>) } <ボタンのonClick={() => handleClick()}></ボタン> </div> ); } デフォルトのアプリをエクスポートします。 答えは「いいえ」です この問題は、Reactレンダリングメカニズムとdiffアルゴリズムに関係しています。 公式ウェブサイトでは、diff に関して次のようなルールが定められています。
上記の問題を分析します。ボタンをクリックするとsetInitMap([1,2,3,4])によりレンダリングが発生します。レンダリング時に新しい仮想DOMが生成されます。ただし、この時に取得するspan要素は前の要素であるため(setInitMapは非同期で実行されるため)、新旧DOMの比較が行われます。
ここでの div はリストです。4 番目の diff ルールと比較して、React はキーに基づいて実際の DOM を更新するかどうかを決定します。 key={Math.random()}の場合、新旧のDOMの値が一致しない場合は、divが再生成されます。更新前に要素に赤いスタイルを追加したので、再作成された要素にはこのスタイルは適用されません。効果は次のようになります。 2番目のケース: キー値がインデックス値である上記の分析の結果、キーの変更により、レンダリング時に div 要素が再生成されることがわかりました。レンダリングの前後でキーが変更されない場合はどうなるでしょうか?たとえば、キーをインデックスに変更する 質問: このコードでボタンをクリックすると、スパンの色は変わりますか? 戻る ( <div className="アプリ" id="アプリ"> <スピン 回転 = {スピン}></スピン> { initMap.map((it,index) => <div key={index}><span>色</span></div>) } <ボタンのonClick={() => handleClick()}></ボタン> </div> ); 回答: はい 分析: レンダリングの前後でインデックスが変更されないため、div は再生成されません。次に、span 要素を比較します。span 要素の属性はレンダリングの前後で変更されるため、React は span 要素に新しい属性のみを適用しますが、それらは依然として前の要素を指します。 3 番目のケース: キー値が決定され、一意です。この例では、キーをindexに設定することで、spanの色が変わりますが、キーを使用する場合、React公式サイトではindexの使用は推奨されていません。 上記のコードを修正する 定数[initMap、setInitMap] = useState([1,2,3,4]); const ハンドルクリック = () => { 初期化マップを設定します([3,2,1,4]) } 戻る ( <div className="アプリ" id="アプリ"> { initMap.map((it,index) => <div key={index}><input type="radio" />{it}</div>) } <button onClick={() => handleClick()}>クリック</button> </div> ); } 初期化時に値3のボタンを選択します ボタンをクリックしてください 期待される効果は、値が 3 のボタンがまだ選択されているが、値が 1 のボタンになることです。 分析:
望ましい効果を達成したい場合は、ユニークで確実なキーを設定する必要がありますテスト1: { initMap.map((it) => <div キー = {it}><input タイプ = "radio" />{it}</div>) } 初期化中に3番目のボタンを選択します ボタンをクリックしてください これは期待される効果です考えてみてください。キーを Math.random() に設定するとどのような効果があるでしょうか?ボタンの状態は保存されますか? クリックする前に: クリック後: 無線状態は保存されません。上記の例を通して、Reactにおけるキーの役割を理解できたと思います。以下の内容はReactの知識ポイントの拡張です。 拡張コンテンツ: 記事の冒頭のコードには、React の他の 2 つの知識ポイントも含まれています。1 つは前述の React のレンダリング条件であり、もう 1 つは実際の DOM の操作です。 拡張1: Reactレンダリング条件 './App.css' をインポートします。 React をインポートし、{useState} を 'react' から取得します。 関数App() { 定数[initMap、setInitMap] = useState([1,2,3,4]); const [spin, setSpin] = useState(false); const ハンドルクリック = () => { setSpin(true); //変更された部分 var spanEle = document.getElementsByTagName('span'); Array.from(spanEle).map(it => it.style.color = 'red') setSpin(false); //パーツを変更} 戻る ( <div className="アプリ" id="アプリ"> <スピン 回転 = {スピン}></スピン> { initMap.map((it,index) => <div key={Math.random()}><span>{it}</span></div>) } <ボタンのonClick={() => handleClick()}></ボタン> </div> ); } デフォルトのアプリをエクスポートします。 クリック前のテスト結果は次のとおりです。 クリック後: このコードでは、div のキーは引き続き Math.random() を使用していますが、initMap の状態は変更されていないため、再レンダリングされません。このとき、div は破棄されずに再構築されます。 拡張 2: 実際の DOM を操作することは可能ですか?React では、実際の DOM 要素はより複雑なオブジェクトであり、操作には多くの計算が必要になるため、仮想 DOM の登場により実際の DOM に対する操作が削減されます。上記のコードでは、DOM ノードを直接操作してスタイルを変更していますが、これはお勧めできません。 React は状態とプロパティの変更に基づいてページをレンダリングするため、状態を通じてページのレンダリングを制御する方が適切です。 変更されたコードは次のとおりです。 関数App() { 定数[initMap、setInitMap] = useState([1,2,3,4]); const [spin, setSpin] = useState(false); const [showColor, setShowColor] = useState(false); const ハンドルクリック = () => { setInitMap([3,2,1,4]); ShowColor を true に設定します。 } 戻る ( <div className="アプリ" id="アプリ"> <スピンスピン={スピン}> { initMap.map((it,index) => <div key={Math.random()}><span className={showColor && 'span-color'}>色</span></div>) } </スピン> <button onClick={() => handleClick()}>クリック</button> </div> ); } このとき、spanは制御されたコンポーネントであり、要素のレンダリングはshowColorの状態によって制御できます。 クリックする前に: クリック後: 状態を使用してレンダリングを制御すると、コードの量が削減され、結果が期待どおりになります。 要約する
以上がReactにおけるキーの役割についての詳しい説明です。Reactキーの役割についてさらに詳しく知りたい方は、123WORDPRESS.COMの他の関連記事もぜひご覧ください! 以下もご興味があるかもしれません:
|
<<: nginx プロキシ サーバーで双方向証明書検証を構成する方法
>>: Nginx の add_header ディレクティブに注意する必要があるのはなぜですか?
目次1. トリガーソリューション2. パーティションテーブルソリューション3. 一般的な表領域ソリュ...
はじめに: Web ページを作成するときに、画像をアップロードする必要がある場合がよくあります。画像...
背景会社のサブプロジェクトが増えるにつれて、さまざまなサイズのプロジェクトが10個以上になります(バ...
1. Dockerコンテナを起動する以下のコマンドを使用して新しい Docker コンテナを起動しま...
PostgreSQL はコンパイルされインストールされるため、起動時に起動するように設定する必要があ...
Mysqldump は MySQL の論理バックアップに使用されます。高速ではありませんが、柔軟性が...
成果を達成する html <h2>CSS3 タイムライン</h2> <...
この記事では、ネイティブ JS で実装されたデジタル時計エフェクトを紹介します。エフェクトは次のとお...
先ほど MySQL パスワードを設定したのに、外食したり荷物を受け取ったりするときにパスワードを忘れ...
序文:この知識を理解する必要がある人は、すでにプロセス間通信とスレッド間通信の基本的な理解を持ってい...
目次テレポートの目的テレポートの仕組みこの記事では、以下の内容を取り上げます。テレポートの目的テレポ...
前提条件: データベースを復元するために必要な .frm ファイルと .ibd ファイルを保存します...
コンテナが起動した後まず管理者にログインして新しいユーザーを作成してください $ docker ex...
1.アルパインイメージをダウンロードする [root@DockerBrian ~]# docker ...
「私たちは次の一連のモバイル製品を HTML5 で作成しています。」 「ええ、最近は多くの人が Ap...