React中如何将响应文本的代码块替换为JSX语法高亮组件?
解决字符串替换JSX返回[Object object]的问题
你的问题核心在于String.replace是字符串操作,它要求替换后的返回值必须是字符串,但你返回的是SyntaxHighlighter这个JSX元素(本质是React对象),对象被强制转为字符串就会变成[object Object]。
要解决这个问题,不能直接用字符串替换,而是要把原始文本拆分成「普通文本片段」和「代码块片段」的数组,再分别渲染成文本和高亮组件。
实现代码
import SyntaxHighlighter from 'react-syntax-highlighter'; import { dark } from 'react-syntax-highlighter/dist/esm/styles/hljs'; function processResponse(response) { // 正则匹配带语言标识的代码块:```语言\n代码内容``` const codeBlockRegex = /```(\w+)?\n([\s\S]*?)```/g; const contentFragments = []; let lastMatchEnd = 0; let matchResult; // 遍历所有匹配到的代码块 while ((matchResult = codeBlockRegex.exec(response)) !== null) { // 把代码块之前的普通文本加入数组 if (matchResult.index > lastMatchEnd) { contentFragments.push(response.slice(lastMatchEnd, matchResult.index)); } // 提取语言标识和代码内容 const codeLanguage = matchResult[1] || 'none'; const codeContent = matchResult[2]; // 把语法高亮组件加入数组 contentFragments.push( <SyntaxHighlighter key={matchResult.index} language={codeLanguage} style={dark} > {codeContent} </SyntaxHighlighter> ); // 更新最后匹配的位置 lastMatchEnd = codeBlockRegex.lastIndex; } // 加入最后一段未匹配的普通文本 if (lastMatchEnd < response.length) { contentFragments.push(response.slice(lastMatchEnd)); } return contentFragments; }
使用方式
在React组件中直接渲染返回的数组即可:
function ResponseComponent({ responseText }) { const formattedContent = processResponse(responseText); return <div className="response-content">{formattedContent}</div>; }
关键说明
- 用
RegExp.exec循环匹配代码块,拆分出普通文本和代码块的位置 - 把普通文本字符串和JSX组件按顺序存入数组,React会自动遍历渲染数组中的每个元素
- 给每个
SyntaxHighlighter组件设置唯一key,符合React列表渲染的要求
内容的提问来源于stack exchange,提问作者ndp
相关产品推荐
相关产品推荐

