如何在@uiw/react-markdown-preview中实现文本流式渲染?
实现@uiw/react-markdown-preview的流式渲染(逐字符展示)
要实现逐字符流式渲染效果,核心思路是通过状态逐步拼接文本内容,定时更新传给MarkdownPreview的source属性,让组件逐步渲染内容。以下是具体的实现方案:
具体实现代码
import { useState, useEffect } from 'react'; import MarkdownPreview from '@uiw/react-markdown-preview'; const fullText = "Here's a JavaScript function that generates the Fibonacci sequence up to a given number:\n\n```javascript\nfunction fibonacci(n) {\n let first = 0;\n let second = 1;\n\n console.log(first);\n console.log(second);\n\n for (let i = 2; i < n; i++) {\n let next = first + second;\n console.log(next);\n [first, second] = [second, next];\n }\n}\n\nfibonacci(10);\n```\n\nThis code will print the Fibonacci sequence up to the 10th number:\n\n0\n1\n1\n2\n3\n5\n8\n13\n21\n34\n\nIf you run this code in a JavaScript environment (like Node.js or a web browser console), it should display these numbers as output."; const StreamMarkdownPreview = () => { const [currentText, setCurrentText] = useState(''); const [currentIndex, setCurrentIndex] = useState(0); // 控制打字速度,单位:毫秒/字符 const typeSpeed = 30; useEffect(() => { if (currentIndex >= fullText.length) return; const timer = setTimeout(() => { setCurrentText(prev => prev + fullText[currentIndex]); setCurrentIndex(prev => prev + 1); }, typeSpeed); return () => clearTimeout(timer); }, [currentIndex]); return ( <MarkdownPreview className="mark-down-box" source={currentText} wrapperElement={{ "data-color-mode": "dark" }} /> ); }; export default StreamMarkdownPreview;
关键说明
- 状态管理:用
currentText存储当前已渲染的文本,currentIndex记录当前处理到的字符位置。 - 定时更新:通过
useEffect监听currentIndex,每次定时器触发时拼接下一个字符,更新状态后触发MarkdownPreview重新渲染。 - 速度控制:调整
typeSpeed变量可以改变流式渲染的快慢,数值越小打字速度越快。
注意事项
逐字符渲染过程中,可能会出现中间状态的Markdown语法不完整(比如代码块还未闭合、标题符号未写完),导致临时的渲染异常。如果要优化这个问题,可以改为按段落/语法块拆分文本,逐段渲染,避免中间状态的语法错误:
- 将完整文本按段落或Markdown块拆分(比如用换行、代码块标记分割)
- 依次渲染每个块,每个块内部再逐字符展示
内容的提问来源于stack exchange,提问作者Arun Ravindran
相关产品推荐
相关产品推荐

