Next.js App路由 Styled-componets 首屏和刷新出现样式闪动
配置next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
compiler: {
styledComponents: true, // 添加
},
};
module.exports = nextConfig;
修改注册样式的代码
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
export default function StyledComponentsRegistry({
children,
}: {
children: React.ReactNode
}) {
// Only create stylesheet once with lazy initial state
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet())
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return styles
})
if (typeof window !== 'undefined') return <>{children}</>
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
StyledComponentsRegistry组件,用于处理在服务器端渲染(Server Side Rendering)中使用styled-components库的样式注册。该组件接收一个
children参数,表示需要渲染的子组件。在组件内部,使用了React的
useState钩子来创建一个styledComponentsStyleSheet的状态变量,其初始值是通过new ServerStyleSheet()创建的ServerStyleSheet实例。接着,使用
useServerInsertedHTML自定义钩子,用于获取在服务器端渲染期间插入的HTML。在钩子回调函数中,首先通过styledComponentsStyleSheet.getStyleElement()获取到样式表元素,然后调用styledComponentsStyleSheet.instance.clearTag()方法来移除样式标签。最后,将获取到的样式表元素返回。接着,通过判断
typeof window !== 'undefined'来确定当前代码执行的环境是服务器端还是客户端。如果是客户端,则直接将children返回。如果是服务器端,则使用
StyleSheetManager组件将styledComponentsStyleSheet.instance作为sheet属性传入,以在子组件中共享样式表。最后,将
children作为子元素渲染在StyleSheetManager组件中。总之,该组件主要用于在服务器端渲染中处理
styled-components的样式注册,并确保在客户端和服务器端的渲染结果一致。