讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在 React 中对带换行符的长字符串进行语法高亮渲染

千辰同学_6530

千辰同学_6530

发布时间:2026-01-08 22:23:02

|

783人浏览过

|

来源于php中文网

原创

如何在 React 中对带换行符的长字符串进行语法高亮渲染

本文介绍在 react 中安全、高效地渲染含 `\n` 换行的代码类字符串,并实现关键词(如 `export`、`const`、`fadeanimation`)的语法着色,兼顾可维护性与性能。

在 React 中直接用 dangerouslySetInnerHTML 渲染含 HTML 标签的字符串虽快,但存在 XSS 风险且无法动态控制样式;而单纯对 \n 做 split().map() 处理(如原逻辑)虽安全,却难以进一步对子词着色。真正健壮的方案是:将字符串解析为带语义的 token 序列,再逐 token 渲染为带样式的 JSX 元素。

以下推荐两种生产就绪的实现方式,均避免内联 HTML 和字符串拼接:

✅ 方案一:预定义 Token 数组(推荐用于静态常量)

适用于内容固定、结构清晰的代码片段(如你的 fadeAnimation 示例):

Cn Password Generator V2
Cn Password Generator V2

生成加密安全的随机密码,支持自定义字符集、长度及字符类型控制,纯 Python 实现,无需 API 密钥。

下载
// 定义带语义的 token 数组(支持嵌套换行与缩进)
export const fadeAnimationTokens: Array<{ 
  type: 'keyword' | 'identifier' | 'punctuation' | 'comment' | 'newline'; 
  text: string; 
  indent?: number; // 缩进层级(单位:px)
}> = [
  { type: 'keyword', text: 'export' },
  { type: 'keyword', text: 'const' },
  { type: 'identifier', text: 'fadeAnimation' },
  { type: 'punctuation', text: '=' },
  { type: 'newline', text: '' },
  { type: 'punctuation', text: '{' },
  { type: 'newline', text: '' },
  { type: 'indent', text: '', indent: 20 },
  { type: 'keyword', text: 'initial' },
  { type: 'punctuation', text: ':' },
  { type: 'punctuation', text: '{' },
  // ... 后续 tokens 省略,按需补充
];

对应渲染组件:

const CodeBlock = ({ tokens }: { tokens: typeof fadeAnimationTokens }) => {
  return (
    <div className="code-block" style={{ fontFamily: 'monospace', fontSize: '14px', lineHeight: '1.5' }}>
      {tokens.map((token, i) => {
        const baseStyle = { color: '#a69a9a' };
        let style = { ...baseStyle };

        switch (token.type) {
          case 'keyword':
            style.color = '#007acc'; // 蓝色:export/const/return 等
            break;
          case 'identifier':
            style.color = '#333'; // 深灰:变量名、函数名
            break;
          case 'punctuation':
            style.color = '#666'; // 灰色:{ } : , =
            break;
          case 'indent':
            return <span key={i} style={{ display: 'inline-block', width: `${token.indent}px` }} />;
          case 'newline':
            return <br key={i} />;
          default:
            break;
        }

        return (
          <span key={i} style={style}>
            {token.text}
            {token.type !== 'newline' && token.type !== 'indent' && ' '}
          </span>
        );
      })}
    </div>
  );
};

// 使用
<CodeBlock tokens={fadeAnimationTokens} />

✅ 方案二:运行时正则分词(适合动态内容)

若字符串来自 props 或 API,可用轻量正则提取关键词并保留原始换行结构:

const highlightCode = (code: string): JSX.Element[] => {
  // 先按 \n 分行,再对每行内关键词着色
  return code.split('\n').map((line, lineIndex) => {
    // 移除首尾空格后判断是否为空行
    const trimmed = line.trim();
    const indentWidth = line.length - trimmed.length;

    // 匹配关键词(支持单词边界,避免误匹配)
    const highlightedLine = trimmed
      .replace(/\b(export|const|let|var|function|return|if|else|for|while)\b/g, 
        (match) => `<span class="keyword">${match}</span>`)
      .replace(/\b([a-zA-Z_$][\w$]*)\b(?=\s*:)/g, 
        (match) => `<span class="identifier">${match}</span>`)
      .replace(/([{}[\]();,])/g, 
        (match) => `<span class="punctuation">${match}</span>`);

    return (
      <div 
        key={lineIndex} 
        style={{ 
          marginLeft: `${indentWidth * 8}px`, // 每空格约 8px(根据字体调整)
          color: '#a69a9a'
        }}
      >
        <span 
          dangerouslySetInnerHTML={{ __html: highlightedLine }} 
        />
        {lineIndex < code.split('\n').length - 1 && <br />}
      </div>
    );
  });
};

// 注意:使用 dangerouslySetInnerHTML 时务必确保 code 来源可信!
// 若不可信,应先用 DOMPurify 清洗 HTML 字符串。

⚠️ 关键注意事项

  • 永远避免在不可信输入上使用 dangerouslySetInnerHTML —— 方案一完全规避此风险,更安全;
  • Token 数组法性能更优:无运行时正则开销,React 可精准 diff;
  • CSS 类名优于内联 style:将 .keyword { color: #007acc; } 写入 CSS 文件,提升可维护性;
  • 缩进处理要一致:建议用 pre + white-space: pre 或显式 marginLeft,避免空格塌陷;
  • 考虑使用专业库:对于复杂语法高亮(如完整 JavaScript),推荐 react-syntax-highlighter 或 Prism。

通过结构化 token 或受控正则分词,你既能精准控制每个词的颜色与间距,又能保持 React 的声明式、可预测性优势——告别字符串拼接和样式混乱。

热门AI工具

更多
切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

5944

2023.10.24

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

12986

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1565

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

3517

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

5681

2024.03.01

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2078

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1658

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2464

2023.09.04

C++运算符基础入门
C++运算符基础入门

本专题详细讲解了C++运算符的类型、语法与使用方法,涵盖算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、条件运算符及其他特殊运算符,并通过代码示例解析优先级与结合性。

0

2026.10.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 1.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 5.9万人学习

CSS教程
CSS教程

共754课时 | 96.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn