在React组件中将HTML字符串呈现为真实HTML

时间:2016-09-28 21:42:04

标签: javascript html reactjs jsx

这是我尝试过的以及它是如何出错的。

这有效:

<div dangerouslySetInnerHTML={{ __html: "<h1>Hi there!</h1>" }} />

这不是:

<div dangerouslySetInnerHTML={{ __html: this.props.match.description }} />

description属性只是HTML内容的正常字符串。然而,由于某种原因,它被渲染为字符串,而不是HTML。

enter image description here

有什么建议吗?

14 个答案:

答案 0 :(得分:52)

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: '&lt;p&gt;&lt;strong&gt;Our Opportunity:&lt;/strong&gt;&lt;/p&gt;'
    }
  }

   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'));

答案 1 :(得分:26)

检查您尝试附加到节点的文本是否没有像这样转义:

var prop = {
    match: {
        description: '&lt;h1&gt;Hi there!&lt;/h1&gt;'
    }
};

而不是:

var prop = {
    match: {
        description: '<h1>Hi there!</h1>'
    }
};

如果被转义,您应该从服务器端转换它。

The node is text because is escaped

节点是文本,因为已转义

The node is a dom node because isn't escaped

节点是dom节点,因为没有转义

答案 2 :(得分:10)

如果您可以控制包含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>
}

答案 3 :(得分:5)

我将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>
}

答案 4 :(得分:4)

我使用了'react-html-parser'

yarn add react-html-parser
import ReactHtmlParser from 'react-html-parser'; 

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

来源on npmjs.com

答案 5 :(得分:3)

如果字符串中包含HTML,我建议使用名为html-react-parser的软件包。

安装:npm install html-react-parser,或者如果使用毛线,则yarn add html-react-parser

使用类似这样的东西

import parse from 'html-react-parser'
const yourHtmlString = '<h1>Hello</h1>'
<div>
    {parse(yourHtmlString)}
</div>

参考:https://www.npmjs.com/package/html-react-parser

答案 6 :(得分:2)

您只使用React的危险的SetInnerHTML方法

<div dangerouslySetInnerHTML={{ __html: htmlString }} />

或者您可以通过这种简单的方法实现更多功能:Render the HTML raw in React app

答案 7 :(得分:2)

危险地设置InnerHTML

dangerouslySetInnerHTML是React在浏览器DOM中使用innerHTML的替代品。通常,通过代码设置HTML是有风险的,因为很容易在无意间使用户遭受跨站点脚本(XSS)攻击。因此,您可以直接从React设置HTML,但是您必须输入angerousedSetInnerHTML并使用__html键传递对象,以提醒自己这很危险。例如:

function createMarkup() {
  return {__html: 'First &middot; Second'};
}

function MyComponent() {
  return <div dangerouslySetInnerHTML={createMarkup()} />;
}

答案 8 :(得分:0)

我无法让npm buildreact-html-parser一起工作。但是,就我而言,我能够成功使用https://reactjs.org/docs/fragments.html。我要求显示一些html unicode字符,但是它们不应该直接嵌入JSX中。在JSX中,必须从组件的状态中选择它。组件代码段如下:

constructor() 
{
this.state = {
      rankMap : {"5" : <Fragment>&#9733; &#9733; &#9733; &#9733; &#9733;</Fragment> , 
                 "4" : <Fragment>&#9733; &#9733; &#9733; &#9733; &#9734;</Fragment>, 
                 "3" : <Fragment>&#9733; &#9733; &#9733; &#9734; &#9734;</Fragment> , 
                 "2" : <Fragment>&#9733; &#9733; &#9734; &#9734; &#9734;</Fragment>, 
                 "1" : <Fragment>&#9733; &#9734; &#9734; &#9734; &#9734;</Fragment>}
                };
}

render() 
{
       return (<div class="card-footer">
                    <small class="text-muted">{ this.state.rankMap["5"] }</small>
               </div>);
}

答案 9 :(得分:0)

就我而言,我使用了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>")

答案 10 :(得分:0)

我使用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>)

答案 11 :(得分:0)

您也可以使用 Jumper Package 中的 parseReactHTMLComponent。看看就行了,很简单,不需要使用JSX语法。

https://codesandbox.io/s/jumper-module-react-simple-parser-3b8c9?file=/src/App.js .

更多关于跳线:

https://github.com/Grano22/jumper/blob/master/components.js

NPM 包:

https://www.npmjs.com/package/jumper_react

答案 12 :(得分:0)

通过<div dangerouslySetInnerHTML={{ __html: htmlString }} /> IT WORK FOR ME。 跟随上面的Hou Soune

解析字符串:'<p>Hello</p>' 到元素 <p>Hello</p>

答案 13 :(得分:-1)

如果您可以控制{this.props.match.description},并且您使用的是JSX。我建议不要使用“ dangerouslySetInnerHTML”。

// In JSX, you can define a html object rather than a string to contain raw HTML
let description = <h1>Hi there!</h1>;

// Here is how you print
return (
    {description}
);