You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件中{this.state.number}输出带引号字符串的原因及解决办法

React渲染HTML字符串显示为带引号文本的原因及解决办法

问题原因

  1. React的自动转义机制:React默认会转义所有渲染的字符串内容,目的是防止XSS注入攻击。你直接把HTML字符串赋值给state后渲染,React会将整个字符串(包括<tr>这类标签)当成普通文本输出,所以会显示带引号的完整字符串内容。
  2. 模板字符串语法错误:你用单引号'包裹HTML片段,里面的{ele.name}不会被解析成变量值,只会作为普通字符串拼接进去。
  3. 不必要的多次状态更新:在forEach循环里多次调用setState,会导致组件频繁重渲染,既影响性能也不符合逻辑。

解决办法

方法一:使用dangerouslySetInnerHTML(不推荐,仅限安全内容)

React提供dangerouslySetInnerHTML属性直接渲染HTML字符串,但存在XSS风险,仅当你完全信任内容来源时使用。

修改要点:

  • 把字符串拼接的单引号改成反引号`,让${ele.name}能被正确解析
  • 将setState移到forEach循环外,只更新一次状态
  • 渲染时用dangerouslySetInnerHTML替代直接输出字符串
// 修改componentDidMount部分
async componentDidMount() {
  let tokensvar = `<tr> <td>1</td> <td>2</td> </tr>`;
  const url = "https://api.multiversx.com/accounts/erd1n0kgesdn7hc63amdfygqfdj9enfa07n2hwup9y8732fg35qcug8q0w0x8s/tokens";
  const response = await fetch(url);
  const data = await response.json();
  
  data.forEach((ele) =>{
    tokensvar += `<tr> <td>${ele.name}</td> <td>${ele.name}</td> </tr>`;
  })
  
  this.setState({ number: tokensvar, loading: false });
}

// 修改render部分
render() {
  // ... 省略loading和空状态判断
  
  return (
    <div>
      <table className="Token-section-output" dangerouslySetInnerHTML={{ __html: this.state.number }} />
    </div>
  );
}

方法二:使用React元素数组(推荐,符合最佳实践)

React的核心是用元素描述UI,而非拼接HTML字符串。直接将接口数据转换成React元素数组渲染,既安全又易维护。

完整修改代码:

import React from "react";

export default class Tokens extends React.Component {
  state = {
    loading: true,
    tokens: [] // 存储原始数据,而非HTML字符串
  };

  async componentDidMount() {
    const url = "https://api.multiversx.com/accounts/erd1n0kgesdn7hc63amdfygqfdj9enfa07n2hwup9y8732fg35qcug8q0w0x8s/tokens";
    try {
      const response = await fetch(url);
      const data = await response.json();
      this.setState({ tokens: data, loading: false });
    } catch (error) {
      console.error("获取数据失败:", error);
      this.setState({ loading: false });
    }
  }

  render() {
    if (this.state.loading) {
      return <div>loading...</div>;
    }

    if (this.state.tokens.length === 0) {
      return <div>没有获取到token数据</div>;
    }

    return (
      <div>
        <table className="Token-section-output">
          <thead>
            <tr>
              <th>名称</th>
              <th>名称</th>
            </tr>
          </thead>
          <tbody>
            {/* 初始固定行 */}
            <tr>
              <td>1</td>
              <td>2</td>
            </tr>
            {/* 遍历数据生成React元素 */}
            {this.state.tokens.map((ele, ind) => (
              <tr key={ind}> {/* 建议使用唯一ID作为key,这里临时用索引 */}
                <td>{ele.name}</td>
                <td>{ele.name}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
}

该方法优势:

  • 彻底避免XSS风险,React自动处理内容转义
  • 代码更易读、易调试,符合React组件化思想
  • 仅更新一次状态,避免不必要的重渲染

内容的提问来源于stack exchange,提问作者August 7337

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:07:07