这是我尝试过的以及它是如何出错的。
这有效:
<div dangerouslySetInnerHTML={{ __html: "<h1>Hi there!</h1>" }} />
这不会:
<div dangerouslySetInnerHTML={{ __html: this.props.match.description }} />
description 属性只是一个普通的 HTML 内容字符串。但是,由于某种原因,它被呈现为字符串,而不是 HTML。
https://i.stack.imgur.com/cI25q.png
有什么建议么?
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'));
我使用'react-html-parser'
yarn add react-html-parser
import ReactHtmlParser from 'react-html-parser';
<div> { ReactHtmlParser (html_string) } </div>
提升@okram 的评论以获得更多可见性:
来自其 github 描述:将 HTML 字符串直接转换为 React 组件,从而避免使用危险的来自 npmjs.com 的 SetInnerHTML 用于将 HTML 字符串转换为 React 组件的实用程序。避免使用 dangerouslySetInnerHTML 并将标准 HTML 元素、属性和内联样式转换为它们的 React 等效项。
Converts HTML strings directly into React components avoiding the need to use dangerouslySetInnerHTML
来自 npmjs.com A utility for converting HTML strings into React components. Avoids the use of dangerouslySetInnerHTML and converts standard HTML elements, attributes and inline styles into their React equivalents.
检查您尝试附加到节点的文本是否没有像这样转义:
var prop = {
match: {
description: '<h1>Hi there!</h1>'
}
};
而不是这个:
var prop = {
match: {
description: '<h1>Hi there!</h1>'
}
};
如果被转义,你应该从你的服务器端转换它。
https://i.stack.imgur.com/LF1X0.png
该节点是文本,因为已转义
https://i.stack.imgur.com/tAKRd.png
该节点是 dom 节点,因为没有转义
如果字符串中有 HTML,我建议使用名为 html-react-parser
的包。
安装
新PM:
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>
如果您可以控制包含 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 布局混淆。当我偶然发现这个问题寻找可能的解决方案时,我想我会分享 我 如何解决问题。
Some text <strong>wrapped with strong</strong>
包含 html 标签 strong
。
This is a String
”(或者只是将一个字符串存储在一个变量中),当你把这个字符串放在我将 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>
}
更新:
我删除了一些 HTML 状态并添加了注释,以使示例在概念上更加简洁。
/**
* example how to retrieve a reference to an html object
*/
import React, { useRef, useEffect } from 'react';
/**
* 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) {
spanRef.current.innerHTML = "some <b>bold</b>";
}
}, [spanRef]);
return <div>
my custom text follows<br />
{/* ref={spanRef] will update the React.RefObject `spanRef` when html obj ready */}
<span ref={spanRef} />
</div>
}
componentDidMount() { this.message.current.innerHTML = this.state.selectedMessage.body; }
body 是我的转义 html。
您只需使用 React 的危险SetInnerHTML 方法
<div dangerouslySetInnerHTML={{ __html: htmlString }} />
或者您可以通过这种简单的方式实现更多功能:Render the HTML raw in React app
就我而言,我使用了 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>")
我无法让 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>);
}
我用 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>)
您还可以使用 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
// 对于打字稿导入解析,{ HTMLReactParserOptions } from "html-react-parser";从“domhandler/lib/node”导入{元素}; export function contentHandler(postContent: string) { const options: HTMLReactParserOptions = { replace: (domNode: Element) => { if (domNode.attribs) { if (domNode.attribs.id === 'shortcode') { return
如果您可以控制 {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}
);
this.props.match.description
是一个字符串,而不是一个对象。错误的标记是什么意思?你的意思是未封闭的标签? React 应该只渲染它吗?<p><strong>Our Opportunity:</strong></p>