React.js:innerHTMLとdangerouslySetInnerHTMLを設定する


171

要素のinnerHTMLを設定することと、要素にdangerouslySetInnerHTMLプロパティを設定することとの「裏側」の違いはありますか?簡単にするために、適切にサニタイズしていると仮定します。

例:

var test = React.createClass({
  render: function(){
    return (
      <div contentEditable='true' dangerouslySetInnerHTML={{ __html: "Hello" }}></div>
    );
  }
});

var test = React.createClass({
  componentDidUpdate: function(prevProp, prevState){
    this.refs.test.innerHTML = "Hello";
  },
  render: function(){
    return (
      <div contentEditable='true' ref='test'></div>
    );
  }
});

上記の例よりも少し複雑なことをしていますが、全体的な考え方は同じです

回答:


236

はい、違いがあります!

innerHTMLvs を使用した直接の影響dangerouslySetInnerHTMLは同じです。DOMノードは、挿入されたHTMLで更新されます。

ただし、バックグラウンドdangerouslySetInnerHTMLで使用すると、Reactはそのコンポーネントの内部のHTMLが重要ではないことを認識します。

Reactは仮想DOMを使用するため、diffを実際のDOMと比較するときに、HTMLが別のソースからのものであることを認識しているため、そのノードの子のチェックを省略できます。したがって、パフォーマンスが向上します。

さらに重要なことに、単にを使用した場合innerHTML、ReactはDOMノードが変更されたことを知ることができません。次にrender関数が呼び出されたときに、Reactは手動で挿入されたコンテンツを、そのDOMノードの正しい状態であると考えるもので上書きします。

componentDidUpdateコンテンツが常に同期していることを確認するために使用するソリューションは機能すると思いますが、各レンダリング中にフラッシュが発生する可能性があります。


11
私は、SVGをインライン化して使用する場合の違いを示すために、小さな、非科学的なPERFテストを書いたdangerouslySetInnerHTMLwebpackbin.com/bins/-KepHa-AMxQgGxOUnAacを -のinnerHTMLメソッドアウトタンズは早くほぼ倍である(webpackbinでコンソールを参照してください)
ジョシャ

4
これは真実であり、簡単に予測できます。innerHTMLは、何も考慮せずにSVGコードを直接DOMにバインドするネイティブメソッドであるためです。一方、dangerouslySetInnerHTMLはReactのメソッドであり、仮想DOMに配置してからDOMにレンダリングする前に、SVGコードをReact Componentの子として解析する必要があります。
Up209d、2018

3

Dangerously Set innerHTMLによると、

を不適切に使用innerHTMLすると、クロスサイトスクリプティング(XSS) 攻撃を受ける可能性があります。表示用にユーザー入力を無害化することは、よく知られているようにエラーが発生しやすく、適切に無害化することの失敗は、インターネット上のWeb脆弱性の主要な原因の1つです。

私たちの設計哲学は、物事を安全にすることは「簡単」である必要があり、開発者は「安全でない」操作を実行するときに意図を明示する必要があるということです。プロップ名dangerouslySetInnerHTMLは恐ろしいように意図的に選択されており、プロップ値(文字列ではなくオブジェクト)を使用して、サニタイズされたデータを示すことができます。

セキュリティの影響を十分に理解し、データを適切にサニタイズした後、キー__htmlとサニタイズされたデータのみを値として含む新しいオブジェクトを作成 します。JSX構文を使用した例を次に示します。

function createMarkup() {
    return {
       __html: 'First &middot; Second'    };
 }; 

<div dangerouslySetInnerHTML={createMarkup()} /> 

以下のリンクを使用して詳細をお読みください:

ドキュメンテーションReact DOM Elements-dangerouslySetInnerHTML


1
これは質問の答えにはなりません。
クエンティン

2

dangerouslySetInnerHTML)に基づいています。

それはまさにあなたが望むものを行う小道具です。ただし、注意して使用する必要があることを示すために名前を付けています


1
ドキュメントによると、これが唯一の理由であり、混乱しているようです
mkb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.