Render HTML string as real HTML in a React component
这是我尝试过的方法以及出现问题的方法。
这有效:
1 | Hi there!" }} /> |
这不是:
1 |
description属性只是HTML内容的普通字符串。 但是由于某种原因,它呈现为字符串,而不是HTML。
有什么建议么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class App extends React.Component { constructor() { super(); this.state = { description: '<h1 style="color:red;">something' } } render() { return ( ); } } ReactDOM.render(<App />, document.getElementById('root')); |
结果:http://codepen.io/ilanus/pen/QKgoLA?editors=1011
但是,如果
something不带引号'' ,您将得到:
1
2
3
4
5
6
7
8
9
10
11
?Object {
$$typeof: [object Symbol] {},
_owner: null,
key: null,
props: Object {
children:"something",
style:"color:red;"
},
ref: null,
type:"h1"
}
1 2 3 4 5 6 7 8 9 10 11 | ?Object { $$typeof: [object Symbol] {}, _owner: null, key: null, props: Object { children:"something", style:"color:red;" }, ref: null, type:"h1" } |
如果它是字符串,并且您没有看到任何HTML标记,那么我看到的唯一问题是标记错误。
更新
如果您正在处理HTMLEntitles。您需要先解码它们,然后再将它们发送到
工作示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class App extends React.Component { constructor() { super(); this.state = { description: '<p> Our Opportunity: </p>' } } htmlDecode(input){ var e = document.createElement('div'); e.innerHTML = input; return e.childNodes.length === 0 ?"" : e.childNodes[0].nodeValue; } render() { return ( ); } } ReactDOM.render(<App />, document.getElementById('root')); |
我用了'react-html-parser'
1 | yarn add react-html-parser |
1 2 3 | import ReactHtmlParser from 'react-html-parser'; { ReactHtmlParser (html_string) } |
源于npmjs.com
提升@okram的评论以提高知名度:
from its github description: Converts HTML strings directly into React
components avoiding the need to use dangerouslySetInnerHTML from
npmjs.com A 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.
检查您尝试追加到节点的文本是否没有被转义,如下所示:
1 2 3 4 5 | var prop = { match: { description: 'Hi there!' } }; |
代替这个:
1 2 3 4 5 | var prop = { match: { description: 'Hi there!' } }; |
如果转义,则应从服务器端进行转换。
该节点是文本,因为已转义
该节点是dom节点,因为没有转义
如果您可以控制包含html的字符串的来源(即,应用程序中的某个位置),则可以从新的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import React, {Fragment} from 'react' const stringsSomeWithHtml = { testOne: ( <Fragment> Some text wrapped with strong </Fragment> ), testTwo: `This is just a plain string, but it'll print fine too`, } ... render() { return {stringsSomeWithHtml[prop.key]} } |
危险地设置内部HTML
angerouslySetInnerHTML是React在浏览器DOM中使用innerHTML的替代品。通常,通过代码设置HTML是有风险的,因为很容易在无意间使用户遭受跨站点脚本(XSS)攻击。因此,您可以直接从React设置HTML,但是您必须输入angerousedSetInnerHTML并使用__html键传递对象,以提醒自己这很危险。例如:
1 2 3 4 5 6 7 | function createMarkup() { return {__html: 'First Second'}; } function MyComponent() { return ; } |
您只使用React的危险的SetInnerHTML方法
或者,您可以通过这种简单的方法实现更多功能:在React应用中渲染HTML原始文件
就我而言,我使用react-render-html
首先通过
然后,
1 2 3 | import renderHTML from 'react-render-html'; renderHTML("GitHub") |
我无法使
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | constructor() { this.state = { rankMap : {"5" : <Fragment>★ ★ ★ ★ ★</Fragment> , "4" : <Fragment>★ ★ ★ ★ ☆</Fragment>, "3" : <Fragment>★ ★ ★ ☆ ☆</Fragment> , "2" : <Fragment>★ ★ ☆ ☆ ☆</Fragment>, "1" : <Fragment>★ ☆ ☆ ☆ ☆</Fragment>} }; } render() { return ( <small class="text-muted">{ this.state.rankMap["5"] }</small> ); } |
如果您可以控制{this.props.match.description}并且使用的是JSX。我建议不要使用" dangerouslySetInnerHTML"。
1 2 3 4 5 6 7 | // In JSX, you can define a html object rather than a string to contain raw HTML let description = Hi there!; // Here is how you print return ( {description} ); |