如何在react-codemirror组件中实现指定文本高亮(如单个字符标红)
解决React-CodeMirror高亮特定字符的问题
要实现aTest bTest cTest中的a、b、c字符红色高亮,你需要用CodeMirror 6的Decoration(装饰)系统来实现,而不是旧版的markTextAPI。下面是完整的实现方案:
完整代码示例
import { useRef, useEffect } from 'react'; import { CodeMirror } from '@uiw/react-codemirror'; import { Decoration, DecorationSet } from '@codemirror/view'; import { EditorState } from '@codemirror/state'; // 定义高亮装饰器:这里直接内联样式,也可以用类名(推荐) const highlightDecoration = Decoration.mark({ attributes: { style: 'color: red; font-weight: bold;' } }); // 或者用类名方式(需配合CSS) // const highlightDecoration = Decoration.mark({ class: 'highlight-red' }); const HighlightEditor = () => { const editorRef = useRef(null); const decorationsRef = useRef(DecorationSet.empty); // 扫描文本,生成所有需要高亮的字符范围 const updateHighlights = (view) => { if (!view) return; const { state } = view; const decorations = []; const text = state.doc.toString(); // 遍历文本,匹配a/b/c字符 for (let i = 0; i < text.length; i++) { if (['a', 'b', 'c'].includes(text[i])) { decorations.push(highlightDecoration.range(i, i + 1)); } } // 更新装饰集合并应用到编辑器 decorationsRef.current = DecorationSet.create(state.doc, decorations); view.dispatch({ effects: Decoration.set(decorationsRef.current, true) }); }; useEffect(() => { const view = editorRef.current?.view; if (!view) return; // 初始化时执行高亮 updateHighlights(view); // 监听编辑器内容变化,自动更新高亮 const updateListener = view.updateListener.of((update) => { if (update.docChanged) { updateHighlights(view); } }); // 组件卸载时清理监听 return () => { view.dispatch({ effects: updateListener.destroy() }); }; }, []); return ( <CodeMirror ref={editorRef} basicSetup={{ lineNumbers: false }} value="aTest bTest cTest" onChange={(value) => console.log("value:", value)} /> ); }; export default HighlightEditor;
关键要点说明
使用Decoration系统:CodeMirror 6推荐用装饰系统来处理文本标记,
Decoration.mark可以创建文本范围的样式装饰,比旧版markText更灵活,符合新版的状态管理逻辑。处理内容更新:通过
view.updateListener监听文档变化,每次内容修改后重新扫描文本并更新高亮,避免内容变化后高亮失效。样式的两种方式:
- 内联样式:直接在装饰器里写
style属性,适合简单场景。 - 类名方式:定义CSS类(比如
.highlight-red { color: red; }),装饰器用class属性,方便样式复用和维护。
- 内联样式:直接在装饰器里写
你之前代码的问题
- API版本不匹配:你用了
view.markText,这是CodeMirror 5的API,而react-codemirror基于CodeMirror 6,API已经变更。 - 依赖项错误:
useEffect依赖refs.current不会正确触发,因为ref的引用不会随内部属性变化而更新,应该用空依赖+内部监听。 - 未处理内容更新:只在初始化时标记,输入新内容后不会重新高亮。
内容的提问来源于stack exchange,提问作者peon123
相关产品推荐
相关产品推荐

