Next.js渲染排序数组报错:Text content不匹配服务端渲染HTML
解决 "Text content does not match server-rendered HTML" 错误
你的问题源于两个核心问题,直接导致了服务端渲染(SSR)与客户端注水(hydration)阶段的内容不匹配:
1. 原地排序修改了原数组
items.sort()是原地排序方法,会直接修改原始的items数组。在SSR场景下,服务端执行排序后已经改变了原数组结构,客户端注水时会再次执行排序,此时原数组已是服务端修改后的版本,两次排序的输入不一致,最终渲染的HTML结构与服务端返回的不匹配,触发错误。
解决方法:创建数组副本再排序,避免修改原数组:
// 用展开运算符创建副本后排序 [...items].sort((a, b) => b.value - a.value) // 或用slice()创建副本 items.slice().sort((a, b) => b.value - a.value)
2. 使用索引作为key的风险
你用index作为React元素的key,当数组顺序变化时,React会错误复用组件实例,既会导致状态混乱,也会加剧SSR与客户端的内容不匹配问题。正确做法是使用每个item的唯一标识,比如item.id。
修改后的完整代码
const items = [ {id: 1, title: 'Topic 1', value: 2}, {id: 2, title: 'Topic 2', value: 5}, {id: 3, title: 'Topic 3', value: 1}, {id: 4, title: 'Topic 4', value: 4}, {id: 5, title: 'Topic 5', value: 3}, ] const App = () => { return ( <div className="flex flex-col gap-4 w-full p-6 items-center"> {[...items].sort((a, b) => b.value - a.value).map((item) => ( <div className="flex gap-2 px-4 items-center h-10 w-full rounded-md text-lg bg-[#ffd700]" key={item.id} > <div> {item.title} {item.value} </div> /5 </div> ))} </div> ) }
额外注意事项
- 确保排序逻辑在服务端与客户端完全一致,不要依赖客户端独有变量(如
window对象)参与排序,否则仍会导致渲染结果不一致。 - 若使用Next.js等框架的静态生成(SSG)或服务器组件,建议在组件外部提前完成排序(确保只执行一次),避免首次渲染闪烁。
内容的提问来源于stack exchange,提问作者smartish
相关产品推荐
相关产品推荐

