我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

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

苏南大叔:react项目,如何输出带html标签的字符串?避免转义 - react-dangerous-html
react项目,如何输出带html标签的字符串?避免转义(图4-1)

大家好,这里是苏南大叔的平行空间笔记本博客,这里记录苏南大叔和计算机代码的故事。本文描述如何在react项目中输出html片段。测试环境:create-react-app@5.0.1react@18.2.0react-dom@18.2.0node@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>
        )
    }
}

从运行结果中,可以看到:这里的变量valthis.state.val2中的html字符都被转义了。

苏南大叔:react项目,如何输出带html标签的字符串?避免转义 - 危险的字符串
react项目,如何输出带html标签的字符串?避免转义(图4-2)

解决方案: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标签的字符串?避免转义 - 危险的字符串2
react项目,如何输出带html标签的字符串?避免转义(图4-3)

思考题目

说实话,上面这些被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呢?答案出乎想象。

苏南大叔:react项目,如何输出带html标签的字符串?避免转义 - 危险的字符串3
react项目,如何输出带html标签的字符串?避免转义(图4-4)

seosn.com:这里是【评论】可见内容

相关链接

总结

react不推荐大家这么做,必然有它合理的理由。所以,大家也就尽量避免这种写法了。更多react经验文章,请点击苏南大叔的博客:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   react