回答:
ノードに追加しようとしているテキストが次のようにエスケープされていないかどうかを確認します。
var prop = {
match: {
description: '<h1>Hi there!</h1>'
}
};
これの代わりに:
var prop = {
match: {
description: '<h1>Hi there!</h1>'
}
};
エスケープされている場合は、サーバー側から変換する必要があります。
エスケープされているため、ノードはテキストです
エスケープされていないため、ノードはdomノードです
DOESはthis.props.match.description
、文字列またはオブジェクトですか?文字列の場合は、HTMLに変換する必要があります。例:
class App extends React.Component {
constructor() {
super();
this.state = {
description: '<h1 style="color:red;">something</h1>'
}
}
render() {
return (
<div dangerouslySetInnerHTML={{ __html: this.state.description }} />
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
結果:http : //codepen.io/ilanus/pen/QKgoLA?editors=1011
ただしdescription: <h1 style="color:red;">something</h1>
、引用符''
がなければ、次のようになります。
Object {
$$typeof: [object Symbol] {},
_owner: null,
key: null,
props: Object {
children: "something",
style: "color:red;"
},
ref: null,
type: "h1"
}
文字列でHTMLマークアップが表示されない場合、唯一の問題は間違ったマークアップです。
更新
HTMLEntitlesを扱っている場合。それらを送信する前にそれらをデコードする必要があるのでdangerouslySetInnerHTML
、彼らはそれを危険に呼び出しました:)
作業例:
class App extends React.Component {
constructor() {
super();
this.state = {
description: '<p><strong>Our Opportunity:</strong></p>'
}
}
htmlDecode(input){
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
render() {
return (
<div dangerouslySetInnerHTML={{ __html: this.htmlDecode(this.state.description) }} />
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
this.props.match.description
オブジェクトではなく文字列です。間違ったマークアップとはどういう意味ですか?閉じられていないタグを意味しますか?Reactはそれをノーにレンダリングするべきですか?
<p><strong>Our Opportunity:</strong></p>
「react-html-parser」を使用しています
yarn add react-html-parser
import ReactHtmlParser from 'react-html-parser';
<div> { ReactHtmlParser (html_string) } </div>
ソースnpmjs.com上
より見やすくするために@okramのコメントを引き上げる:
githubの説明から:HTML文字列を直接Reactコンポーネントに変換します。npmjs.comのdangerouslySetInnerHTMLを使用する必要がありません。HTML文字列をReactコンポーネントに変換するユーティリティです。dangerouslySetInnerHTMLの使用を回避し、標準のHTML要素、属性、インラインスタイルを対応するReactに変換します。
Converts HTML strings directly into React components avoiding the need to use dangerouslySetInnerHTML
から:npmjs.comA utility for converting HTML strings into React components. Avoids the use of dangerouslySetInnerHTML and converts standard HTML elements, attributes and inline styles into their React equivalents.
htmlを含む文字列がどこから来ているか(つまり、アプリのどこか)を制御している場合は<Fragment>
、次のような新しいAPI を利用できます。
import React, {Fragment} from 'react'
const stringsSomeWithHtml = {
testOne: (
<Fragment>
Some text <strong>wrapped with strong</strong>
</Fragment>
),
testTwo: `This is just a plain string, but it'll print fine too`,
}
...
render() {
return <div>{stringsSomeWithHtml[prop.key]}</div>
}
Fragment
APIが登場する以前は、常に面倒でした。そのため、追加のspan
ラップが必要になり、場合によってはフレックスレイアウトが混乱することがありました。可能な解決策を探すためにこの質問に出くわしたとき、私は物事を回避する方法を共有したいと思いました。
Some text <strong>wrapped with strong</strong>
が含まれていますstrong
。つまり、htmlタグが含まれています。
ReactのdangerouslySetInnerHTMLメソッドを使用するだけです
<div dangerouslySetInnerHTML={{ __html: htmlString }} />
または、次の簡単な方法でさらに実装することもできます。ReactアプリでHTMLをそのままレンダリングする
dangerouslySetInnerHTML
dangerouslySetInnerHTMLは、ブラウザのDOMでinnerHTMLを使用するためのReactの代替品です。一般に、ユーザーが誤ってクロスサイトスクリプティング(XSS)攻撃にさらされる可能性があるため、コードからHTMLを設定することは危険です。したがって、Reactから直接HTMLを設定できますが、危険であることを思い出させるために、dangerouslySetInnerHTMLと入力して__htmlキーでオブジェクトを渡す必要があります。例えば:
function createMarkup() {
return {__html: 'First · Second'};
}
function MyComponent() {
return <div dangerouslySetInnerHTML={createMarkup()} />;
}
私はinnerHTMLを使用してrefをスパンします:
import React, { useRef, useEffect, useState } from 'react';
export default function Sample() {
const spanRef = useRef<HTMLSpanElement>(null);
const [someHTML,] = useState("some <b>bold</b>");
useEffect(() => {
if (spanRef.current) {
spanRef.current.innerHTML = someHTML;
}
}, [spanRef.current, someHTML]);
return <div>
my custom text follows<br />
<span ref={spanRef} />
</div>
}
componentDidMount() { this.message.current.innerHTML = this.state.selectedMessage.body; }
ボディはエスケープされたhtmlです。
私の場合、react-render-htmlを使用しました
最初にパッケージをインストールします npm i --save react-render-html
その後、
import renderHTML from 'react-render-html';
renderHTML("<a class='github' href='https://github.com'><b>GitHub</b></a>")
で仕事をすることができませんでしnpm build
たreact-html-parser
。しかし、私の場合、https://reactjs.org/docs/fragments.htmlをうまく利用することができました。いくつかのHTML Unicode文字を表示する必要がありましたが、JSXに直接埋め込むべきではありません。JSX内では、コンポーネントの状態から選択する必要がありました。コンポーネントコードスニペットを以下に示します。
constructor()
{
this.state = {
rankMap : {"5" : <Fragment>★ ★ ★ ★ ★</Fragment> ,
"4" : <Fragment>★ ★ ★ ★ ☆</Fragment>,
"3" : <Fragment>★ ★ ★ ☆ ☆</Fragment> ,
"2" : <Fragment>★ ★ ☆ ☆ ☆</Fragment>,
"1" : <Fragment>★ ☆ ☆ ☆ ☆</Fragment>}
};
}
render()
{
return (<div class="card-footer">
<small class="text-muted">{ this.state.rankMap["5"] }</small>
</div>);
}
https://www.npmjs.com/package/html-to-reactを使用します
const HtmlToReactParser = require('html-to-react').Parser;
let htmlInput = html.template;
let htmlToReactParser = new HtmlToReactParser();
let reactElement = htmlToReactParser.parse(htmlInput);
return(<div>{reactElement}</div>)