React Emotion在SSR中样式异常,需额外配置?实现方案排查
React Emotion SSR样式问题排查与配置方案
问题背景
使用React Emotion开发时,非服务端渲染(SSR)场景样式表现正常,但开启SSR后出现样式异常,需排查代码问题并明确SSR所需的额外配置。
代码问题排查与修复
1. 全局Emotion Cache实例导致跨请求样式污染
你的代码中cache是在renderServerSide函数外全局创建的,这会导致多个请求共享同一个缓存实例,不同请求的样式会互相覆盖,引发样式错乱。
修复: 将Cache创建逻辑移到renderServerSide内部,为每个请求生成独立的Cache实例:
async function renderServerSide(req, res) { try { // 每个请求创建独立的cache const key = 'custom'; const cache = createCache({ key }); const { extractCriticalToChunks, constructStyleTagsFromChunks } = createEmotionServer(cache); // ... 后续代码 } }
2. 重复执行渲染与样式提取,导致样式丢失/重复
代码中同时调用了extractCritical和extractCriticalToChunks,且两次执行ReactDOMServer.renderToString,这会导致Emotion的样式缓存被重复写入,最终提取的样式可能不完整或重复。
修复: 保留一套样式提取逻辑,只执行一次渲染操作:
// 移除extractCritical相关代码 // const content = extractCritical(ReactDOMServer.renderToString(JSX)); // 仅执行一次渲染并提取样式 const html = ReactDOMServer.renderToString(JSX); const chunks = extractCriticalToChunks(html); const appStyles = constructStyleTagsFromChunks(chunks); // 将完整的html传递给Html组件 const page = ( <Html content={html} // 替换为渲染后的完整html // ... 其他props /> );
3. 客户端需匹配服务端Cache配置并完成样式Hydrate
服务端使用了自定义key的Cache,客户端必须使用相同的key创建Cache,同时确保Hydrate时复用服务端注入的样式,避免客户端重新生成样式导致页面闪烁。
客户端入口示例代码:
import { CacheProvider } from '@emotion/react'; import createCache from '@emotion/cache'; // 与服务端使用相同的key const cache = createCache({ key: 'custom' }); ReactDOM.hydrateRoot( document.getElementById('root'), <CacheProvider value={cache}> {/* 应用根组件 */} </CacheProvider> );
4. 确保CacheProvider包裹整个应用
确认clientModules.getWrappedRoot没有额外嵌套组件导致CacheProvider作用范围不足,所有使用Emotion编写样式的组件必须在CacheProvider的包裹范围内。
总结
React Emotion实现SSR的关键配置要点:
- 每个请求独立创建Emotion Cache实例,避免跨请求样式污染
- 服务端正确提取样式并注入到HTML头部
- 客户端使用与服务端一致的Cache配置,完成样式Hydrate
- 确保
CacheProvider包裹整个应用组件树
内容的提问来源于stack exchange,提问作者Mubina
相关产品推荐
相关产品推荐

