React-小道具でHTMLタグを渡す方法は?


118

次のように、HTMLタグを使用してテキストを渡すことができるようにしたいと思います。

<MyComponent text="This is <strong>not</strong> working." />

しかし、MyComponentのrenderメソッドの内部ではthis.props.text、出力すると文字通りすべてが出力されます。

This is <strong>not</strong> working.

ReactがHTMLを解析して適切にダンプする方法はありますか?


実際のレンダリング機能は何ですか?
Lucio、

3
一般的なパターンは、コンテンツ<MyComponent>This is <strong>not</strong> working</MyComponent>を小道具として渡すのではなく、コンポーネントの子にすることです。実際に達成しようとしていることについて、より詳しい説明をお願いできますか?
Nick Tomlin、2015年

ほぼ同じ質問:Reactjsがhtmlに変換されます。
totymedli 2017

回答:


140

文字列とJSX要素を持つ混合配列を使用できます(こちらのドキュメントを参照):

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />

それが機能していることを示すフィドルがあります:http : //jsfiddle.net/7s7dee6L/

また、最後の手段として、常に生のHTMLを挿入できますが、プロパティ値をサニタイズしないとクロスサイトスクリプティング(XSS)攻撃を受ける可能性があるため、注意が必要です。


10
これは機能しますが、警告が表示されます:警告:配列または反復子の各子には、一意の「キー」プロップが必要です。CTAのレンダリング方法を確認してください。Template1から子が渡されました。詳細については、fb.me / react-warning-keysを参照してください。
ffxsam

3
配列を調べ、MyComponentにキーとしてインデックスを追加することで、このエラーを解消できます {text.map( textOrHTML, index) => <span key={index}>{textOrHTML}</span> )}
HussienK 2016

5
要素を置くことkey="[some unique value]"で警告を修正することもでき<strong>ます。
Chad Johnson

うまくいきました。文字列 'not'の代わりにstrong内の変数をどのように使用できるのか知りたいのですが
Jaison

2
配列キーの警告を削除するために、このように単一のJSXを渡すことも可能です。<MyComponent text={<>This is <strong>not</strong> working.</>} />
Arif

111

実際、それにはいくつかの方法があります。

プロップ内でJSXを使用したい

単に{}を使用して、JSXにパラメータを解析させることができます。唯一の制限は、すべてのJSX要素と同じです。ルート要素を1つだけ返す必要があります。

myProp={<div><SomeComponent>Some String</div>}

このための最も読みやすい方法は、JSXコンポーネントを返す関数renderMyPropを作成し(標準のレンダー関数のように)、次にmyProp = {this.renderMyProp()}を呼び出すだけです。

HTMLのみを文字列として渡したい

デフォルトでは、JSXでは文字列値から生のHTMLをレンダリングできません。ただし、それを行う方法があります。

myProp="<div>This is some html</div>"

次に、コンポーネントでそれをそのように使用できます:

<div dangerouslySetInnerHTML=myProp={{ __html: this.renderMyProp() }}></div>

このソリューションは、クロスサイトスクリプティングフォージェリ攻撃に対して「開く」ことができることに注意してください。また、レンダリングできるのは単純なHTMLのみであり、JSXタグやコンポーネント、その他の凝ったものはレンダリングされないことに注意してください。

アレイウェイ

反応では、JSX要素の配列を渡すことができます。つまり:

myProp={["This is html", <span>Some other</span>, "and again some other"]}

次の理由により、この方法はお勧めしません。

  • 警告が表示されます(キーがありません)
  • 読めない
  • これは実際にはJSXの方法ではなく、意図した設計というよりはハックです。

子供の道

完全を期すために追加しますが、反応すると、コンポーネントの「内部」にあるすべての子を取得することもできます。

だから私が次のコードを取る場合:

<SomeComponent>
    <div>Some content</div>
    <div>Some content</div>
</SomeComponent>

その後、2つのdivは、SomeComponentのthis.props.childrenとして使用可能になり、標準の{}構文でレンダリングできます。

このソリューションは、コンポーネントに渡すHTMLコンテンツが1つしかない場合に最適です(Popinのコンテンツのみを子として取得するPopinコンポーネントを想像してください)。

ただし、複数のコンテンツがある場合は、子を使用できません(または、少なくともここで別のソリューションと組み合わせる必要があります)


1
this.props.childrens-しかしthis.props.children。's'を使用し
Alexiuscrow

13

あなたはdangerouslySetInnerHTMLを使用することができます

htmlを通常の文字列として送信するだけです

<MyComponent text="This is <strong>not</strong> working." />

そして、次のようにJSXコードでレンダリングします。

<h2 className="header-title-right wow fadeInRight"
    dangerouslySetInnerHTML={{__html: props.text}} />

ユーザーが入力したデータをレンダリングする場合は注意してください。あなたはXSS攻撃の犠牲になることができます

ここにドキュメントがあります:https : //facebook.github.io/react/tips/dangerously-set-inner-html.html


7
<MyComponent text={<span>This is <strong>not</strong> working.</span>} />

次に、コンポーネントで次のようにプロップチェックを実行できます。

import React from 'react';
export default class MyComponent extends React.Component {
  static get propTypes() {
    return {
      text: React.PropTypes.object, // if you always want react components
      text: React.PropTypes.any, // if you want both text or react components
    }
  }
}

プロップタイプは1つだけ選択してください。


6

小道具の子供にhtmlタグを渡すことで機能しました

<MyComponent>This is <strong>not</strong> working.</MyComponent>


var MyComponent = React.createClass({

   render: function() {
    return (
      <div>this.props.children</div>
    );
   },


6

クライアント側の反応アプリケーションでは、いくつかのhtmlを含む文字列としてプロップをレンダリングする方法がいくつかあります。1つは他より安全です...

1-プロップをjsxとして定義します(私の好み)

const someProps = {
  greeting: {<div>Hello<a href="/${name_profile}">${name_profile}</a></div>}
}


const GreetingComopnent = props => (
  <p>{props.someProps.greeting}</p>
)

•ここでの唯一の要件は、この小道具を生成するファイルが依存関係としてReactを含める必要があることです(ヘルパーファイルなどで小道具のjsxを生成する場合)。

2-危険な方法でinnerHtmlを設定する

const someProps = {
  greeting: '<React.Fragment>Hello<a href="https://stackoverflow.com/${name_profile}">${name_profile}</a></React.Fragment>'
}

const GreetingComponent = props => {
  const innerHtml = { __html: props.someProps.greeting }
  return <p dangerouslySetInnerHtml={innerHtml}></p>
}

•この2番目のアプローチはお勧めしません。このコンポーネントの入力値が小道具としてレンダリングされる入力フィールドを想像してください。ユーザーがスクリプトタグを入力に入力すると、この入力をレンダリングするコンポーネントがこの潜在的に悪意のあるコードを実行します。そのため、このアプローチには、クロスサイトスクリプティングの脆弱性が生じる可能性があります。詳細については、Reactの公式ドキュメントを参照してください。


4

テキストプロップタイプをanyに設定し、これを実行します。

<MyComponent text={
    <React.Fragment>
        <div> Hello, World!</div>
    </React.Fragment>
    } 
/>


3

私が知っている2つの方法でそれを行うことができます。

1- <MyComponent text={<p>This is <strong>not</strong> working.</p>} />

そしてこれを行う

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.text}</div>)
   }
}

または2番目のアプローチはこのようにします

2- <MyComponent><p>This is <strong>not</strong> working.</p><MyComponent/>

そしてこれを行う

class MyComponent extends React.Component {
   render () {
     return (<div>{this.props.children}</div>)
   }
}

1
私は変数を追加し、let vhtml = "<p>Test</p>"このようにプロップで使用しましたがtext={vhtml}、何らかの理由でプレーンテキストでレンダリングされました。
Si8

2

@matagusの回答は私にとっては問題ありません。以下のスニペットが、変数を内部で使用したい場合に役立ちます。

const myVar = 'not';
<MyComponent text={["This is ", <strong>{`${myVar}`}</strong>,  "working."]} />

1

私のプロジェクトでは、変数から動的HTMLスニペットを渡して、コンポーネント内にレンダリングする必要がありました。だから私は次のことをしました。

defaultSelection : {
    innerHtml: {__html: '<strong>some text</strong>'}
}

defaultSelectionオブジェクトが.jsファイルからコンポーネントに渡されます

<HtmlSnippet innerHtml={defaultSelection.innerHtml} />

HtmlSnippetコンポーネント

var HtmlSnippet = React.createClass({
  render: function() {
    return (
      <span dangerouslySetInnerHTML={this.props.innerHtml}></span>
    );
  }
});

Plunkrの例

DangerlylySetInnerHTMLに対するドキュメントの反応


1

コンポーネントの関数を使用して、jsxをpropsに渡すこともできます。お気に入り:

 var MyComponent = React.createClass({

   render: function() {
    return (
      <OtherComponent
        body={this.body}
      />
    );
   },

   body() {
     return(
       <p>This is <strong>now</strong> working.<p>
     );
   }

});

var OtherComponent = React.createClass({

  propTypes: {
    body: React.PropTypes.func
  },

  render: function() {
     return (
        <section>
          {this.props.body()}
        </section>
     );
  },

});

1

はい、文字列とJSX要素を含む混合配列を使用することで実現できます。 参照

<MyComponent text={["This is ", <strong>not</strong>,  "working."]} />

1

パーサのhtml-反応-パーサは良い解決策です。あなたはただしなければならない

  • npmまたはyarnでインストールしてください
  • 'html-react-parser'からパーサーをインポートします。
  • で呼び出す:

    <MyComponent text=Parser("This is <strong>not</strong> working.") />

    そしてそれはうまくいきます。


1

回答への追加:解析するつもりで、すでにJSXを使用しているが、ネストされたプロパティを持つオブジェクトがある場合、JSX解析を強制するために括弧を使用するのが非常にエレガントな方法です。

const TestPage = () => (
  <Fragment>
    <MyComponent property={
    {
      html: (
        <p>This is a <a href='#'>test</a> text!</p>
      )
    }}>
    </MyComponent>
  </Fragment>
);

1

この質問にはすでに多くの答えがありますが、これに関連して何か間違ったことをしていたので、共有する価値があると思います:

私はこのようなものを持っていました:

export default function Features() {
  return (
    <Section message={<p>This is <strong>working</strong>.</p>} />
  }
}

しかし、マッサージはそれよりも長かったので、私は次のようなものを使ってみました:

const message = () => <p>This longer message is <strong>not</strong> working.</p>;

export default function Features() {
  return (
    <Section message={message} />
  }
}

関数呼び出しで()が欠落していることに気付くのにしばらく時間がかかりました。

動かない

<Section message={message} />

ワーキング

<Section message={message()} />

多分これは私にしたようにあなたを助けます!


1

このタスクでは、Reactフラグメントをうまく利用できます。使用するReactのバージョンに応じて、短い構文:<>または完全なタグ:を使用できます<React.Fragment>。HTMLタグ内で文字列全体をラップしたくない場合は、特に効果的です。

<MyComponent text={<>Hello World. <u>Don't be so ruthless</u>.</>} />

0

同じようにして同じことができます。

const Child = () => {
  return (
     write your whole HTML here.
  )
}

次に、このHTMLを、親コンポーネントという名前の別のコンポーネント内に送信します。

呼び出し:-

<Parent child={<child/>} >
</Parent> 

子供の使用:-

 const Parent = (props) => {
   const { child } = props; 
   return (
       {child}
    )
}

この作品は私にぴったりです。


-9

jQuery appendを使用して、componentDidMountにhtmlを追加しました。これで問題が解決するはずです。

 var MyComponent = React.createClass({
    render: function() {

        return (
           <div>

           </div>
        );
    },
    componentDidMount() {
        $(ReactDOM.findDOMNode(this)).append(this.props.text);
    }
});

5
ブラウザのスラッシングにつながる可能性があるため、jqueryの直接的なDOM操作とreactの間接的なDOM操作を組み合わせて使用​​するべきではないため、これは反対票です。
Allison
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.