简体   繁体   English

ReactJS 将 HTML 字符串转换为 JSX

[英]ReactJS convert HTML string to JSX

I'm having trouble dealing with facebook's ReactJS. Whenever I do ajax and want to display an html data, ReactJS displays it as text.我在处理 facebook 的 ReactJS 时遇到问题。每当我执行 ajax 并想要显示 html 数据时,ReactJS 会将其显示为文本。 (See figure below) (见下图)

ReactJS 渲染字符串

The data is displayed through the success callback function of the jquery Ajax.通过jquery Ajax的成功回调function显示数据。

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

在此处输入图像描述

Is there any easy way to convert this into html?有什么简单的方法可以将其转换为 html 吗? How should I do it using ReactJS?我应该如何使用 ReactJS 进行操作?

By default, React escapes the HTML to prevent XSS (Cross-site scripting) .默认情况下,React 会转义 HTML 以防止XSS(跨站点脚本) If you really want to render HTML, you can use the dangerouslySetInnerHTML property:如果你真的想渲染 HTML,你可以使用dangerouslySetInnerHTML属性:

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

React forces this intentionally-cumbersome syntax so that you don't accidentally render text as HTML and introduce XSS bugs. React 强制使用这种有意繁琐的语法,这样您就不会意外地将文本呈现为 HTML 并引入 XSS 错误。

There are now safer methods to accomplish this.现在有更安全的方法来实现这一点。 The docs have been updated with these methods.文档已使用这些方法进行了更新

Other Methods其他方法

  1. Easiest - Use Unicode, save the file as UTF-8 and set the charset to UTF-8.最简单- 使用 Unicode,将文件另存为 UTF-8,并将charset设置为 UTF-8。

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

  2. Safer - Use the Unicode number for the entity inside a Javascript string.更安全- 对 Javascript 字符串中的实体使用 Unicode 编号。

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

    or或者

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

  3. Or a mixed array with strings and JSX elements.或者带有字符串和 JSX 元素的混合数组。

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

  4. Last Resort - Insert raw HTML using dangerouslySetInnerHTML .最后的手段- 使用dangerouslySetInnerHTML SetInnerHTML 插入原始 HTML。

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

I recommend using Interweave created by milesj .我建议使用交织产生的milesj Its a phenomenal library that makes use of a number if ingenious techniques to parse and safely insert HTML into the DOM.它是一个非凡的库,它利用了一些巧妙的技术来解析 HTML 并将其安全地插入到 DOM 中。

Interweave is a react library to safely render HTML, filter attributes, autowrap text with matchers, render emoji characters, and much more. Interweave 是一个反应库,可以安全地呈现 HTML、过滤属性、使用匹配器自动换行文本、呈现表情符号字符等等。

  • Interweave is a robust React library that can: Interweave 是一个强大的 React 库,它可以:
    • Safely render HTML without using dangerouslySetInnerHTML.在不使用危险的SetInnerHTML 的情况下安全地呈现HTML。
    • Safely strip HTML tags.安全地剥离 HTML 标签。
    • Automatic XSS and injection protection.自动 XSS 和注入保护。
    • Clean HTML attributes using filters.使用过滤器清理 HTML 属性。
    • Interpolate components using matchers.使用匹配器插入组件。
    • Autolink URLs, IPs, emails, and hashtags.自动链接 URL、IP、电子邮件和主题标签。
    • Render Emoji and emoticon characters.渲染表情符号和表情符号。
    • And much more!以及更多!

Usage Example:用法示例:

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
npm i html-react-parser;

import Parser from 'html-react-parser';

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

For those still experimenting, npm install react-html-parser对于那些仍在试验中的人, npm install react-html-parser

When I installed it it had 123628 weekly downloads.当我安装它时,它每周有 123628 次下载。

import ReactHtmlParser from 'react-html-parser'

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

You can use the following if you want to render raw html in React如果要在 React 中呈现原始 html,可以使用以下命令

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

Example - Render示例 - 渲染

Test is a good day考试是个好日子

i found this js fiddle.我发现了这个 js 小提琴。 this works like this这就像这样

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 link jsfiddle链接

You can also use Parser() from html-react-parser.您还可以使用 html-react-parser 中的 Parser()。 I have used the same.我也用过。 Link shared.链接共享。

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

This could have been solved by using the content put inside this block {[]} like this.这可以通过使用像这样放置在这个块{[]}的内容来解决。 Example could be referred below for better clarity.为了更清楚,可以在下面引用示例。

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

This would preserve the formatting for text under tags while the others would be printed as plain text.这将保留标签下文本的格式,而其他文本将作为纯文本打印。

If you know ahead what tags are in the string you want to render;如果您事先知道要呈现的字符串中有哪些标签; this could be for example if only certain tags are allowed in the moment of the creation of the string;例如,如果在创建字符串时只允许某些标签; a possible way to address this is use the Trans utility:解决此问题的一种可能方法是使用 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>
  )
}

then you can use it as always然后你可以像往常一样使用它

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

This is very simple .很简单
And it works perfectly .工作得很好

 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;

One option that's missing in the existing answers is using <React.Fragment> ( available in React v16 and later ).现有答案中缺少的一个选项是使用<React.Fragment>在 React v16 及更高版本中可用)。 I find this best because this allows you to store any html element as a JSX variable and refer to it later.我觉得这是最好的,因为这允许您将任何 html 元素存储为 JSX 变量并在以后引用它。 Also because using dangerouslySetInnerHTML is not secure.也因为使用dangerouslySetInnerHTML是不安全的。

For Example例如

 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>

Other alternatives and considerations:其他选择和考虑:

  1. If you don't have any keys or attributes, you can also use <></> which is a shorthand for <React.Fragment></React.Fragment>如果你没有任何键或属性,你也可以使用<></> ,它是<React.Fragment></React.Fragment>的简写
  2. Keep in mind that dangerouslySetInnerHTML is dangerous to use because malicious client side code can be injected via script tags: https://stackoverflow.com/a/42380982/6908282请记住,使用dangerouslySetInnerHTML很危险,因为恶意客户端代码可以通过脚本标签注入: https : //stackoverflow.com/a/42380982/6908282
  3. @Brett has also suggested other alternatives: https://stackoverflow.com/a/27938353/6908282 @Brett 还建议了其他替代方案: https ://stackoverflow.com/a/27938353/6908282

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM