273

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

ReactJS 渲染字符串

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

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

在此处输入图像描述

有什么简单的方法可以将其转换为 html 吗?我应该如何使用 ReactJS 来做到这一点?

4

13 回答 13

488

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

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

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

于 2013-10-09T16:34:22.507 回答
89

现在有更安全的方法来实现这一点。文档已使用这些方法进行了更新。

其他方法

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

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

  2. 更安全- 对 Javascript 字符串中的实体使用 Unicode 编号。

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

    或者

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

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

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

  4. 最后的手段- 使用dangerouslySetInnerHTML.

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

于 2015-01-14T08:10:10.143 回答
55

我推荐使用由milesj创建的Interweave。它是一个了不起的库,它利用了许多巧妙的技术来解析 HTML 并将其安全地插入 DOM。

Interweave 是一个反应库,可以安全地渲染 HTML、过滤属性、使用匹配器自动换行文本、渲染 emoji 字符等等。

  • Interweave 是一个强大的 React 库,它可以:
    • 安全地呈现 HTML,而无需使用 dangerouslySetInnerHTML。
    • 安全地去除 HTML 标签。
    • 自动 XSS 和注入保护。
    • 使用过滤器清理 HTML 属性。
    • 使用匹配器插入组件。
    • 自动链接 URL、IP、电子邮件和主题标签。
    • 渲染表情符号和表情符号。
    • 以及更多!

使用示例:

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
于 2017-11-07T13:29:47.013 回答
22
npm i html-react-parser;

import Parser from 'html-react-parser';

<td>{Parser(this.state.archyves)}</td>
于 2019-12-02T05:28:06.163 回答
9

对于那些仍在试验的人, npm install react-html-parser

当我安装它时,它每周有 123628 次下载。

import ReactHtmlParser from 'react-html-parser'

<div>{ReactHtmlParser(htmlString)}</div>
于 2020-04-22T20:30:52.750 回答
8

如果要在 React 中呈现原始 html,可以使用以下内容

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

示例 - 渲染

考试是个好日子

于 2020-06-15T14:19:05.313 回答
7

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

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

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

于 2020-11-26T12:36:59.583 回答
6

我找到了这个 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链接

于 2016-01-22T23:58:41.793 回答
5

我开始使用名为 react-html-parser 的 npm 包

于 2018-08-14T09:24:09.890 回答
4

您还可以使用 html-react-parser 中的 Parser()。我也用过。链接已分享。

于 2018-04-13T09:46:40.363 回答
1

现有答案中缺少的一个选项是使用<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 解析器(如html-react-parser)解析 HTML
  2. 如果您没有任何键或属性,您也可以使用<></>which 是<React.Fragment></React.Fragment>
  3. 请记住,这dangerouslySetInnerHTML 是很危险的,因为可以通过脚本标签注入恶意客户端代码:
  4. @Brett 还提出了其他替代方案
  5. 注意:在 JSX Variale 中使用引号
    • 你不应该用引号包围一个 JSX 变量(就像一个常规变量) - 你应该用它包围它<React.Fragment> </ React.Fragment>
    • 您不应该在 JSX 变量的 html 标记中转义引号 - 例如,上面的titlein<abbr />标记包含未转义的引号。
于 2021-11-01T21:35:36.483 回答
0

很简单
而且效果很好

import {settings} from '../settings';


const NavBar = (props) => {
    
    let isLoggedIn=props.isLoggedIn;

    let login_partial = "";
    if(isLoggedIn)
    {login_partial= <li>Log Out</li>;}
    else{
    login_partial=
  <div>
      <li>Login</li>
    <li>Sign Up</li>
</div>;
   }

    return(
        <div>
               <ul>
                    <li>Home</li>
                    <li>Products</li>
                    {login_partial}
                </ul>
        </div>
    )
}
export default NavBar;
于 2021-09-22T06:38:17.180 回答
0

如果您事先知道要呈现的字符串中有哪些标签;例如,如果在创建字符串时只允许某些标签;解决此问题的一种可能方法是使用 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>'}
/>
于 2021-02-25T18:06:04.180 回答