非ドム属性?
dangerouslySetInnerHTML,ref,key
非 dom 標準属性、つまり dom 標準には指定された属性がありません。上記のように、React では 3 つの非 dom 属性が導入されています。
dangerouslySetInnerHTML: 文字通り、内部 HTML を危険に設定するこの属性の機能は、HTML コードを jsx に直接挿入することです。 HTML コードを挿入するためにこの属性を使用するのはなぜですか?コードを書くときに直接書くのではなく?コードを記述するときに、どのコードを挿入するかを確認できないことがあります。これは、HTML コードのこの部分が動的に生成されていることを意味します。つまり、なぜこの動作が危険なのかというと、クロスサイト攻撃という言葉がありますが、その理由を例に挙げてみましょう。ページに表示されるコンテンツがあり、このコンテンツはユーザーの入力から取得されます。ユーザーの入力には js コードや html コードなどのコードが含まれているとします。テストせずに直接使用する場合は、この dom をページに挿入します。その後、他の人がそのページにアクセスすると、その人が書いたコードが実行されてしまい、ユーザーの意図が判断できないため、トロイの木馬への接続を追加するなど、非常に危険なコードを書き込む可能性があります。これは非常に危険ですが、動的にコードを記述する必要があるため、react は依然としてこの属性を提供していますが、この属性が非常に危険であることが明確に示されています。 , なので使用しないようにしましょう。
ref: 親コンポーネントが子コンポーネントを参照するとき、親コンポーネントが子コンポーネントを参照するときにネストを使用することがよくあります。実際に使用する場合、ref は親コンポーネント内に多くの参照を保持しており、各参照は対応する子コンポーネントを参照するため、親コンポーネント内のこれらの参照を通じて子コンポーネントを操作できます。親コンポーネントの親コンポーネントを操作できないのはなぜですか?これは実際にはコードの問題ではなく、設計の問題です。react でコンポーネントを使用する目的は、各コンポーネントが独自の機能とロジックを考慮するだけでよく、誰が使用しているかを気にする必要がありません。したがって、コンポーネントはそれ自身の親コンポーネントを参照する必要がありません。親コンポーネントとコンポーネント間の対話は、後で説明する属性の転送によって実現されます。ただし、このような転送は一方向であり、つまり、属性は常に上から下に転送され、下のコンポーネントは上のコンポーネントを制御しません。これは、ロジックを明確にするためです。
重要: レンダリング パフォーマンスを向上させます。 React の特徴の 1 つは、手動による DOM 操作を削除し、完全に自動で実装するため、パフォーマンスが優れていることです。ただし、自動実装では、一連のアルゴリズムを使用する必要があることがわかります。ページ変更に対応する変更を反映するためにページを効率的に変更する方法を決定するアルゴリズム。このアルゴリズムは diff と呼ばれることが多く、これは、2 つの状態の差を計算することを意味します。
反応差分アルゴリズム
React diff アルゴリズムのフローチャート
まず第一に、今比較しているのは 2 つのコンポーネントであることを明確にする必要があります。そのため、2 つのコンポーネントがどのように比較されるかを理解している限り、他の構造でも比較できます。比較のためにコンポーネントに分割して使用します。
一番左側が開始です。開始後の最初の判断は、ノードが同じであるか、div と div が同じであるか、div と p が異なるか、またはカスタマイズされた HelloMessage と HelloMessage が同じであるかどうかです。 HelloWorld と同じコンポーネントではありません。ノードが同じであれば、react は古いノードを直接破棄し、新しいノードを生成します。 2 つのノードが異なる場合、その内容は大きく異なります。ノードが異なる場合は、比較を直接終了し、新しいノードを生成します。ノードが同じである場合、次のステップは、これらのポイントがカスタム ノードであるか dom の標準ノードであるかを判断することです。 divs または HelloWorld がカスタム ノードではなく、標準ノードである場合、react が実行する必要がある次のステップは、クラス、ID などの 2 つのノードの属性を比較することです。属性がまったく同じである場合は、2 つのノードが同じであることを意味し、比較は終了します。たとえば、新しい属性がある場合は、異なる属性を書き留めて変更を適用します。新しい属性、欠落している属性が 1 つある場合は、次のように属性を削除します。つまり、react は古いノードを削除せず、そのノード上でのみ操作します。カスタム ノードの場合、react はそれを再レンダリングします。コンポーネントには多くの状態があるため、新しいコンポーネントは古いコンポーネントの状態にすぎない可能性があります。 Reac 新しい状態が古いコンポーネントに渡され、コンポーネントのレンダリング結果が比較されて変更が加えられます。つまり、react はコンポーネントを再生成しませんが、古いコンポーネントに変更を加えます。これがプロセス全体の diff アルゴリズムです。では、鍵は何に使われるのでしょうか?キーの役割は主にノードの比較に反映されます。つまり、親ノードに複数の子ノードがあるとします。キーが存在せずに変更を加えると、React は愚かな結果を比較します。たとえば、変更前はノード 1 のみでした。変更後、ノード 2 を挿入すると、ノード 2 とノード 1 になります。その後、react によって実行される操作は、ノード 1 を削除し、ノードを追加することです。 2、ノード 1 を追加します。つまり、react は、新しい状態のノード 1 がその状態のノード 1 と同じかどうかを判断できないため、たとえ同じであっても、異なるノードをすべて削除することしかできません。これはパフォーマンスの問題を引き起こすため、キーを導入する目的は、各ノードに一意の識別子を追加することです。このようにして、React は、どのノードが元のノードでどのノードが新しく追加されたノードであるかを知ることができます。先ほどの例では、ノード 1 がノード 2 になります。 1. この時点で、react はノード 2 を挿入する 1 つの操作だけを行う必要があります。ノード 1 のキーが同じであるため、ノード 1 は同じであることを意味します。ノードになり、変化はありません。
この原則を理解すると、React コンポーネントを作成する際にどのようなインスピレーションが得られますか?
最初のポイントは、2 つのコンポーネントが非常に似ている場合は、それらを 1 つのコンポーネントとして記述してみるということです。これは、そのプロセスで、たとえその内容が非常に似ていたとしても、2 つの異なるコンポーネントが確実に再生成されることがわかったためです。 2 番目の発見は、同様のリストを使用して要素を表示する場合、要素にキーを追加することで効率が大幅に向上し、不必要なパフォーマンスの低下を回避できるということです。
非 dom 属性を使用するには?
危険なことに、instance
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var rawHTML={ __html:"<h1>I am inner HTML</h1>" }; var HelloWorld=React.createClass({ render: function(){ return <p>Hello,world</p> } }); React.render(<div style={style} dangerouslySetInnerHTML={rawHTML}></div>,document.body); </script> </body> </html>
ref インスタンスでは、参照を通じて取得するものは dom ノード自体ではないことに注意してください。つまり、テキストの設定などの dom 間の操作を実行できません。これは不可能です。取得できるのは単なる仮想 dom ノード。これは、react によって表示される dom ノードです。実際の dom ノードを取得したい場合は、後で説明しますが、react はこれを行うことを推奨しません。特殊な状況では dom ノードを操作する必要がありますが、それ以外の場合は、react が操作に役立ちます
この例は完了していません。後で説明していきます。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var rawHTML={ __html:"<h1>I am inner HTML</h1>" }; var HelloWorld=React.createClass({ render: function(){ this.refs.childp return <p ref="childp">Hello,world</p> } }); React.render(<div style={style} dangerouslySetInnerHTML={rawHTML}></div>,document.body); </script> </body> </html>
Key インスタンス: キーの値は各コンポーネント内で異なる必要があることに注意してください。キーはコンポーネント内にあることに注意してください。 2 つのコンポーネント間にはそのような制限はありません。
次の 2 つの点に注意してください: 1. 類似したコンテンツを持つコンポーネントを同じコンポーネントにマージするようにしてください。 2. リスト タイプの要素には一意のキーを追加する必要があります。これらの 2 つの点を実行することで、多くのパフォーマンスの問題を回避できます。