React渲染自定义标签SyntaxHighlighter时如何保留大小写?
问题解决:React中保留组件标签大小写及语法高亮实现
问题根源
你用dangerouslySetInnerHTML或react-html-parser渲染时,SyntaxHighlighter被转成小写的根本原因是:这两种方式都是把字符串当作原生HTML解析,而HTML标签名不区分大小写,浏览器会自动将自定义标签转为小写。但SyntaxHighlighter是React组件,需要在React的JSX渲染流程中处理,原生HTML解析无法识别React组件,自然会导致失效。
解决方案
方案一:改用纯前端语法高亮库(无需React组件)
放弃替换标签的思路,直接用highlight.js或prism.js这类库处理原生<pre><code>标签:
- 安装依赖:
npm install highlight.js - 在Post组件中处理:
这种方法无需修改从CMS获取的原始HTML,直接渲染后让库自动处理高亮,简单高效。import hljs from 'highlight.js'; import 'highlight.js/styles/github-dark.css'; // 引入样式 import { useEffect } from 'react'; const Post = ({ postContent }) => { useEffect(() => { hljs.highlightAll(); // 遍历页面中所有带language-*类的code标签,自动高亮 }, [postContent]); return <div dangerouslySetInnerHTML={{ __html: postContent }}></div>; };
方案二:用html-react-parser自定义解析节点(保留React组件)
使用html-react-parser替代原生解析,它支持自定义转换DOM节点为React组件,不会出现标签名小写的问题:
- 安装依赖:
npm install html-react-parser - 组件中配置解析逻辑:
这种方式直接将原生的import parse from 'html-react-parser'; import { SyntaxHighlighter } from 'react-syntax-highlighter'; import { dark } from 'react-syntax-highlighter/dist/esm/styles/hljs'; const Post = ({ postContent }) => { const parseOptions = { replace: (domNode) => { // 匹配<pre>下带language-*类的<code>节点 if (domNode.type === 'tag' && domNode.name === 'pre') { const codeNode = domNode.children.find(child => child.type === 'tag' && child.name === 'code' && child.attribs.class?.includes('language-') ); if (codeNode) { const language = codeNode.attribs.class.split('-')[1]; const codeContent = codeNode.children.map(child => child.data || '').join('').trim(); return ( <SyntaxHighlighter language={language} style={dark}> {codeContent} </SyntaxHighlighter> ); } } return undefined; // 其他节点按默认方式解析 } }; return <div>{parse(postContent, parseOptions)}</div>; };<pre><code>节点转换成React的SyntaxHighlighter组件,完全在React渲染流程中处理,不会出现标签名大小写问题。
内容的提问来源于stack exchange,提问作者Prajwal
相关产品推荐
相关产品推荐

