import React, { memo, useEffect, useState, useRef } from 'react' interface AnimatedStreamingTextProps { text: string className?: string loading?: boolean } export const AnimatedStreamingText = memo(({ text, className, loading }: AnimatedStreamingTextProps) => { const [displayedSegments, setDisplayedSegments] = useState([]) const prevTextRef = useRef('') useEffect(() => { const currentText = (text || '').trim() const prevText = prevTextRef.current if (currentText === prevText) return if (!currentText.startsWith(prevText) && prevText !== '') { // 如果不是追加而是全新的文本(比如重新识别),则重置 setDisplayedSegments([currentText]) prevTextRef.current = currentText return } const newPart = currentText.slice(prevText.length) if (newPart) { // 将新部分作为单独的段加入,以触发动画 setDisplayedSegments(prev => [...prev, newPart]) } prevTextRef.current = currentText }, [text]) // 处理 loading 状态的显示 if (loading && !text) { return 转写中... } return ( {displayedSegments.map((segment, index) => ( {segment} ))} ) }) AnimatedStreamingText.displayName = 'AnimatedStreamingText'