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 ディレクティブに注意する必要があるのはなぜですか?
最近、webpackの使い方を学んでいたときに、webpack-replace-loaderの設定正...
最近、たくさんの人に改変してもらったフレームワークに取り組んでいます。毎日コードを見ていると目が回り...
レンダリング サンプルコード今日は、WeChat アプレットを使用して 2048 ゲームを実装します...
最初の方法: docker インストール1. オープンソース版のイメージを取得する2. 対応するデー...
WeChatアプレットはスクロールビューを使用して左右のリンクを実現します。参考までに、具体的な内容...
目次js のイベントイベントタイプ一般的なイベントイベント登録静的および動的登録の例onload 読...
目次方法1方法2 nginxをインストールした後、PHPコードを解析できないことがわかりました。解決...
1. 事前に準備する便宜上、ここで 2 つのテーブルを作成し、そこにいくつかのデータを追加します。果...
タイマー効果: <div> <font id='timeCount'...
目次基本的なデータベース操作2) データベースを表示する3) データベースを選択する4) データベー...
MySQL 結合クエリ1. 基本概念2 つのテーブルの各行をペアで水平に接続して、すべての行の結果を...
この記事では、ORDER BY文の最適化について学びます。その前に、インデックスの基礎的な理解が必要...
1. Docker 起動時の異常なパフォーマンス: 1. ステータスが繰り返し再起動している場合は、...
目次変数のスコープ閉鎖の概念クロージャの使用クロージャのデメリット最後に、クロージャのメリットとデメ...
Centos yumフォルダを開くコマンドcd /etc/yum.repos.d/を入力します。 w...