服务端渲染(SSR)场景下客户端重复获取页面内容的原因咨询
嘿,这个问题我太熟了!在SSR场景下客户端重复发起请求,大概率是这几个坑导致的:
客户端未正确读取服务端传递的初始状态
服务端把页面所需数据塞进serverApp-state(通常挂载到全局变量比如window.__INITIAL_STATE__)后,很多时候客户端代码根本没做“先检查初始状态,再决定是否请求”的判断。比如React组件里直接在useEffect里发起请求,完全不管全局变量里有没有现成数据;或者用SWR、React Query这类库时,没把初始状态作为initialData传入,导致库默认触发新请求。数据序列化/反序列化出问题
服务端传递状态时一般会把数据序列化成JSON格式,但有些数据类型(比如Date对象、正则、Map)JSON没法直接序列化,转成字符串后客户端反序列化时识别不出来,就会认为数据不存在,进而重新请求。举个例子:服务端传的是new Date(),序列化后变成了字符串"2024-05-20T12:00:00.000Z",客户端如果没把它转成Date对象,组件可能觉得这不是预期的时间类型,就会重新拉取数据。服务端与客户端的路由/组件逻辑不一致
服务端渲染的页面路由和客户端的路由匹配规则有差异,比如服务端用了某个路由参数解析逻辑,客户端却用了另一种,导致客户端认为当前页面是全新的,触发数据请求。或者组件在服务端和客户端的初始化条件不同——比如服务端渲染时用了某个后端专属的判断条件,客户端没有这个条件,就会重新执行数据获取逻辑。状态管理库初始化不到位
如果用Redux、Pinia这类状态管理工具,服务端会把预取的状态注入到客户端,但如果客户端没有正确初始化store(比如Redux没调用createStore时传入初始状态,Pinia没在客户端同步服务端的state),客户端的store就是空的,组件拿不到数据自然会重新请求。第三方数据库未做缓存同步
像React Query、SWR这类库,服务端渲染时会生成查询缓存,但如果客户端没有做hydrate(比如React Query的hydrate函数)把服务端的缓存同步到客户端的QueryClient里,客户端的缓存就是空的,库会默认重新发起请求。
内容的提问来源于stack exchange,提问作者Armin




