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
但是,如果描述是没有引号''
的<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标记,我唯一看到的问题就是错误的标记。
更新
如果你正在处理HTML实体,你需要在发送到"dangerouslySetInnerHTML"之前将它们解码,这就是为什么它被称为 "危险" :)
工作示例:class App extends React.Component {
constructor() {
super();
this.state = {
description: '<p><strong>Our Opportunity:</strong></p>'
}
}
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'));
yarn add react-html-parser
import ReactHtmlParser from 'react-html-parser';
<div> { ReactHtmlParser (html_string) } </div>
来源 npmjs.com
将@okram的评论提高可见性:
根据其Github描述:将HTML字符串直接转换为React组件,避免使用dangerouslySetInnerHTML。这是一个将HTML字符串转换成React组件的实用工具。它避免了使用dangerouslySetInnerHTML,并将标准的HTML元素、属性和内联样式转换为它们的React等效物。
将 HTML 字符串直接转换为 React 组件,避免使用 dangerouslySetInnerHTML。
从 npmjs.com:
将 HTML 字符串转换为 React 组件的实用工具。避免使用 dangerouslySetInnerHTML,并将标准的 HTML 元素、属性和内联样式转换为它们的 React 等效项。
- okram如果您需要处理字符串中的HTML,我建议使用一个名为html-react-parser
的包。
NPM:
npm install html-react-parser
yarn:
yarn add html-react-parser
import parse from 'html-react-parser'
const yourHtmlString = '<h1>Hello</h1>'
代码:
<div>
{parse(yourHtmlString)}
</div>
如果您可以控制包含HTML的字符串来自何处(即在应用程序中的某个地方),则可以使用新的<Fragment>
API进行如下操作:
如果您可以控制包含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>
}
Fragment
API之前,对我来说总是很麻烦,需要额外的span
包裹,有时会影响flex布局。当我在寻找可能的解决方案时偶然发现了这个问题,我想分享一下我是如何解决的。 - Brad Adamsimport 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>
}
/**
* example how to retrieve a reference to an html object
*/
import React, { useRef, useEffect } from 'react';
import * as DOMPurify from 'dompurify'; // add with yarn add DOMPurify and @types/DOMPurify
/**
* this component can be used into another for example <Sample/>
*/
export default function Sample() {
/**
* 1) spanRef is now a React.RefObject<HTMLSpanElement>
* initially created with null value
*/
const spanRef = useRef<HTMLSpanElement>(null);
/**
* 2) later, when spanRef changes because html span element with ref attribute,
* follow useEffect hook will triggered because of dependent [spanRef].
* in an if ( spanRef.current ) that states if spanRef assigned to valid html obj
* we do what we need : in this case through current.innerHTML
*/
useEffect(() => {
if (spanRef.current) {
// follow malicious code injects
// spanRef.current.innerHTML = "sample xss<img src onerror=\"alert('code exec')\"/>";
// follow malicious code will sanitized to <img src>
spanRef.current.innerHTML = DOMPurify.sanitize("sample xss prevented<img src onerror=\"alert('code exec')\"/>")
}
}, [spanRef]);
return <div>
my custom text follows<br />
{/* ref={spanRef] will update the React.RefObject `spanRef` when html obj ready */}
<span ref={spanRef} />
</div>
}
this.message.current.innerHTML = this.state.selectedMessage.body;
}```
body对我来说是转义后的HTML。
- webhound你可以使用React的dangerouslySetInnerHTML方法
<div dangerouslySetInnerHTML={{ __html: htmlString }} />
或者你可以使用这个简单的方法进一步实现:在React应用中原样呈现HTML
在我的情况下,我使用了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>")
使用React内置的dangerouslySetInnerHTML
,并配合好的HTML清理器(如sanitize-html)。
<div dangerouslySetInnerHTML={{
__html: sanitizeHtml(dirtyHTMLString)
}}></div>
我尝试过的所有HTML解析器都会剥离一些我不想要的HTML,而且花时间查找文档以弄清如何停止这种情况是不值得的。
通过像这样使用dangerouslySetInnerHTML
,您可以对HTML进行消毒,使其不那么危险。
npm build
与react-html-parser
配合使用。然而,在我的情况下,我能够成功地利用https://reactjs.org/docs/fragments.html。我需要展示一些HTML Unicode字符,但它们不应直接嵌入JSX中。在JSX内部,它必须从组件的状态中获取。组件代码片段如下:constructor()
{
this.state = {
rankMap : {"5" : <Fragment>★ ★ ★ ★ ★</Fragment> ,
"4" : <Fragment>★ ★ ★ ★ ☆</Fragment>,
"3" : <Fragment>★ ★ ★ ☆ ☆</Fragment> ,
"2" : <Fragment>★ ★ ☆ ☆ ☆</Fragment>,
"1" : <Fragment>★ ☆ ☆ ☆ ☆</Fragment>}
};
}
render()
{
return (<div class="card-footer">
<small class="text-muted">{ this.state.rankMap["5"] }</small>
</div>);
}
this.props.match.description
是一个字符串,而不是一个对象。你说的错误标记是什么意思?你是指未关闭的标签吗?React 应该只是渲染它,对吧? - Sergio Tapiavar returnString = ''; for (index = 0; index < e.childNodes.length; index++) { // case of just a string if(e.childNodes[index].nodeValue){ returnString += e.childNodes[index].nodeValue; } // case of HTML if(e.childNodes[index].outerHTML){ returnString += e.childNodes[index].outerHTML; } } return returnString;
} - Chris Adams