react项目,如何输出带html标签的字符串?避免转义
发布于 作者:苏南大叔 来源:程序如此灵动~
react可以使用{}来输出变量,一般来说,这些变量都可以理解为字符串。但是,在实际的项目中,这个字符串很有可能是一个html片段。那么,问题就来了,如果还使用传统的方式输出字符串的话,这里的html标签就会被转义输出。这显然并不是程序原本的逻辑。这个问题该如何解决呢?

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文描述如何在react项目中输出html片段。测试环境:create-react-app@5.0.1,react@18.2.0,react-dom@18.2.0,node@16.14.2。
传统的写法会被转义
这里还是拿传统的写法来做这个实验,
import React, { Component, useRef } from 'react'
export default class Child extends Component {
constructor(props) {
super(props);
this.state = { val: "非html", val2: "<span style='color:red'>html值</span>" };
}
render() {
var val ="<strong>可以自定义的字符串</strong>";
return (
<div>
<div>{val}</div>
<div>{this.state.val2}</div>
</div>
)
}
}从运行结果中,可以看到:这里的变量val和this.state.val2中的html字符都被转义了。

解决方案:dangerouslySetInnerHTML
由于react认为:这种在变量里面使用html字符的行为是个非常危险的行为。所以,默认是对其进行转义的。如果非要使用这种带html标签的字符串的话。官方给出的解决方案是:dangerouslySetInnerHTML,使用范例如下:
<div dangerouslySetInnerHTML={{ __html:val }} />关键代码是:
dangerouslySetInnerHTML={{ __html:val }} 就是说这个react dom元素中,通过特殊的props执行了一个非常特殊的形式参数dangerouslySetInnerHTML。实际参数的值是:{{ __html:val }}。别问为啥这个写法这么麻烦,react官方就是不想让大家这么操作,才故意设置的这么困难的。
那么,对于大多数的val来说,本来是包裹在元素里面的字符串。但是,这里却变成了元素的一个特殊属性。测试代码如下:
import React, { Component, useRef } from 'react'
export default class Child extends Component {
constructor(props) {
super(props);
this.state = { val: "非html", val2: "<span style='color:red'>html值</span>" };
}
render() {
return (
<div>
<div dangerouslySetInnerHTML={{ __html: this.state.val }} />
<div dangerouslySetInnerHTML={{ __html: this.state.val2 }} />
<div dangerouslySetInnerHTML={{ __html: '<strong>html值</strong>' }} />
</div>
)
}
}另外,需要特别说明的是:
- 这种
dangerouslySetInnerHTML写法,和是函数式组件还是类式组件,是没有关系的。 - 与数据是存放在单独变量还是
state里面,也是没有关系的。

思考题目
说实话,上面这些被react定义为危险的html,苏南大叔觉得一点都不危险。个人认为:稍稍有点危险的地方是执行script标签。所以,关于下面的代码:
import React, { Component, useRef } from 'react'
export default class Child extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div dangerouslySetInnerHTML={{ __html: '<script>alert("危险");</script>' }} />
</div>
)
}
}你猜到底是执行了这个alert了呢?还是没有执行这个alert呢?答案出乎想象。
相关链接
- https://newsn.net/say/react-state.html
- https://newsn.net/say/react-memo.html
- https://newsn.net/say/react-pure-component.html
- https://newsn.net/say/create-react-app.html
总结
react不推荐大家这么做,必然有它合理的理由。所以,大家也就尽量避免这种写法了。更多react经验文章,请点击苏南大叔的博客: