ReactJS转换HTML字符串到JSX

我在处理facebook的ReactJS时遇到了麻烦。每当我使用ajax并想要显示html数据时,ReactJS将其显示为文本。(见下图)

ReactJS渲染字符串

数据通过jquery Ajax的成功回调函数显示。

$.ajax({
url: url here,
dataType: "json",
success: function(data) {
this.setState({
action: data.action
})
}.bind(this)
});

enter image description here

有没有什么简单的方法把它转换成html?我应该如何使用ReactJS?

340418 次浏览

默认情况下,React转义HTML以防止XSS(跨站点脚本)。如果你真的想渲染HTML,你可以使用dangerouslySetInnerHTML属性:

<td dangerouslySetInnerHTML=\{\{__html: this.state.actions}} />

React强制使用这种有意为之的繁琐语法,这样您就不会意外地将文本呈现为HTML并引入XSS错误。

现在有更安全的方法来实现这一点。文档已更新与这些方法。

其他方法

  1. 简单的 -使用Unicode,将文件保存为UTF-8并将charset设置为UTF-8。

    <div>{'First · Second'}</div> < / p >

  2. 更安全的 -为Javascript字符串中的实体使用Unicode数字。

    <div>{'First \u00b7 Second'}</div>

    <div>{'First ' + String.fromCharCode(183) + ' Second'}</div> < / p >

  3. 或包含字符串和JSX元素的混合数组。

    <div>{['First ', <span>&middot;</span>, ' Second']}</div> < / p >

  4. 最后的手段 -插入原始HTML使用dangerouslySetInnerHTML

    <div dangerouslySetInnerHTML=\{\{__html: 'First &middot; Second'}} /> < / p >

我发现了这把js小提琴。它是这样工作的

function unescapeHTML(html) {
var escapeEl = document.createElement('textarea');
escapeEl.innerHTML = html;
return escapeEl.textContent;
}


<textarea className="form-control redactor"
rows="5" cols="9"
defaultValue={unescapeHTML(this.props.destination.description)}
name='description'></textarea>

jsfiddle链接

我建议使用由milesj创建的交织。它是一个非凡的库,使用了许多巧妙的技术来解析HTML并安全地将其插入DOM。

Interweave是一个react库,可以安全地渲染HTML,过滤器 属性,自动抓取文本与匹配器,渲染表情符号字符,和 更多。< / p >
  • Interweave是一个健壮的React库,可以:
    • 安全地渲染HTML而不使用dangerlysetinnerhtml。
    • 安全地剥离HTML标记。
    • 自动XSS和注射保护。
    • 使用过滤器清洁HTML属性。
    • 使用匹配器插入组件。
    • 自动链接url, ip,电子邮件和标签。
    • 渲染表情符号和表情符号字符。
    • 还有更多!
    • 李< / ul > < / >

    使用的例子:

    import React from 'react';
    import { Markup } from 'interweave';
    
    
    const articleContent = "<p><b>Lorem ipsum dolor laboriosam.</b> </p><p>Facere debitis impedit doloremque eveniet eligendi reiciendis <u>ratione obcaecati repellendus</u> culpa? Blanditiis enim cum tenetur non rem, atque, earum quis, reprehenderit accusantium iure quas beatae.</p><p>Lorem ipsum dolor sit amet <a href='#testLink'>this is a link, click me</a> Sunt ducimus corrupti? Eveniet velit numquam deleniti, delectus  <ol><li>reiciendis ratione obcaecati</li><li>repellendus culpa? Blanditiis enim</li><li>cum tenetur non rem, atque, earum quis,</li></ol>reprehenderit accusantium iure quas beatae.</p>"
    
    
    <Markup content={articleContent} /> // this will take the articleContent string and convert it to HTML markup. See: https://milesj.gitbook.io/interweave
    
    
    
    
    //to install package using npm, execute the command
    npm install interweave
    
你也可以从html-react-parser中使用Parser()。 我也用过。链接共享。< / p >

我开始使用NPM包react-html-parser

npm i html-react-parser;


import Parser from 'html-react-parser';


<td>{Parser(this.state.archyves)}</td>

对于那些还在尝试的人,npm安装react-html-parser

当我安装它时,它的周下载量是123628次。

import ReactHtmlParser from 'react-html-parser'


<div>{ReactHtmlParser(htmlString)}</div>

如果你想在React中渲染原始html,可以使用下面的方法

<div dangerouslySetInnerHTML=\{\{__html: `html-raw-goes-here`}} />

示例-渲染

测试是美好的一天

这可以通过使用{[]}块中的内容来解决。为了更清楚,可以参考下面的示例。

{[
'abc',
<b>my bold</b>,
'some other text'
]}

这将保留标签下文本的格式,而其他文本将作为纯文本打印。

如果你提前知道你想呈现的字符串中有哪些标签;例如,如果在创建字符串时只允许某些标记;解决这个问题的一个可能的方法是使用Trans实用程序:

import { Trans } from 'react-i18next'
import React, { FunctionComponent } from "react";


export type MyComponentProps = {
htmlString: string
}


export const MyComponent: FunctionComponent<MyComponentProps> = ({
htmlString
}) => {
return (
<div>
<Trans
components=\{\{
b: <b />,
p: <p />
}}
>
{htmlString}
</Trans>
</div>
)
}

然后你就可以一如既往地使用它了

<MyComponent
htmlString={'<p>Hello <b>World</b></p>'}
/>

现有答案中缺少的一个选项是使用<React.Fragment> (在React v16及更高版本中可用)。我发现这是最好的,因为这允许你将任何html元素存储为JSX变量并在以后引用它。也因为使用dangerouslySetInnerHTML是不安全的。

例如

const App = () => {
const Windows = <React.Fragment>Microsoft <abbr title="Operating System">OS</abbr></React.Fragment>


return (
<ul>
<li>{Windows}</li>
</ul>
);
};


ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

其他选择和考虑:

  1. 如果从外部源获取HTML,则不能使用此方法,因为所获取的HTML将采用字符串格式。在这种情况下,你需要使用像html-react-parser这样的HTML解析器来解析HTML
  2. 如果你没有任何键或属性,你也可以使用<></><React.Fragment></React.Fragment>的缩写
  3. 请记住dangerouslySetInnerHTML 使用是危险的,因为恶意客户端代码可以通过脚本标记注入:
  4. @Brett还建议其他备选方案:
  5. 注意:在JSX变量中使用引号
    • 你不应该用引号(就像一个正则变量)包围一个JSX变量——你应该用<React.Fragment> </ React.Fragment>包围它
    • 你不应该在JSX变量的html标记中转义引号——例如上面<abbr />标记中的title有没有转义的引号。