遍历CMS富文本数据渲染时匹配strong和hyperlink如何避免重复渲染
问题根源
重复渲染的核心原因是你对同一个文本块的每个span都独立渲染了一次完整的文本内容,当同一个文本块同时存在strong和hyperlink两个span时,自然会输出两次相同内容。
最优解决方案
不要逐个遍历span渲染整段内容,每个文本块仅渲染一次,先聚合当前文本块的所有span类型,优先判断组合类型场景,再处理单一类型场景,修改后的代码如下:
<div className='text-left mt-12 text-white'> <h1 className='text-5xl mb-4 font-header text-blue-500'> {RichText.asText(data.title)} </h1> {data.content.map((t, i) => { // 提取当前文本块的所有span类型 const spanTypes = new Set(t.spans.map(item => item.type)) // 提取超链接配置(如果存在) const hyperlink = t.spans.find(item => item.type === 'hyperlink') // 处理列表项(list-item一般为文本块类型,而非span类型,可按需调整) if (t.type === 'list-item') { return ( <ul className='list-disc' key={i}> <li className='text-lg mt-4 text-white'>{t.text}</li> </ul> ) } // 无样式普通文本 if (!t.spans.length) { return ( <p className={`text-lg mt-6 opacity-80 ${t.type}`} key={i}> {t.text} </p> ) } // 同时有粗体+超链接的组合场景,优先处理 if (spanTypes.has('strong') && spanTypes.has('hyperlink')) { return ( <a href={hyperlink.data.url} target='_blank' rel="noopener noreferrer" className={`text-xl mt-6 font-bold text-blue-500 ${t.type}`} key={i} > {t.text} </a> ) } // 仅粗体场景 if (spanTypes.has('strong')) { return ( <p className={`text-xl mt-6 font-bold ${t.type}`} key={i}> {t.text} </p> ) } // 仅超链接场景 if (spanTypes.has('hyperlink')) { return ( <a href={hyperlink.data.url} target='_blank' rel="noopener noreferrer" className={`text-lg opacity-80 mt-6 text-blue-500 ${t.type}`} key={i} > {t.text} </a> ) } // 其他类型兜底 return ( <p className={`text-lg opacity-80 mt-6 ${t.type}`} key={i}> {t.text} </p> ) })} </div>
如果后续业务存在同一段文本里部分内容加粗、部分内容是链接的场景,可以根据span返回的start和end下标切割原文本分段渲染即可。
内容的提问来源于stack exchange,提问作者Asher
相关产品推荐
相关产品推荐

