英文:
styled-components CSS are not applied in NextJS 13
问题
我在我的项目中使用NextJs(版本13.4.10)和styled-components(版本6.0.4)。当我首次运行项目(npm run dev)时,所有样式都会正常应用,但如果我更改代码并重新渲染它,样式就不再起作用。
这是我的代码:
"use client";
import React from "react";
import Image from "next/image";
import { BannerWrapper, ImageBannerWrapper, BannerTitle } from "./style";
export default function Banner() {
return (
<>
<ImageBannerWrapper className="absolute flex">
<Image
src="/images/banner/Mask-banner.png"
height={709}
width={747}
alt="banner"
/>
<BannerTitle className="font-primary text-9xl text-white text-left font-normal">
<span className="font-primary text-9xl text-white text-left font-semibold">
Let us guide you to the best choice.
</span>
</BannerTitle>
</ImageBannerWrapper>
<BannerWrapper className="flex items-center bg-default -mt-16" />
</>
);
}
请注意,我没有翻译代码部分,只提供了代码的原文。
英文:
I am using NextJs (version 13.4.10) and styled-components (version 6.0.4) in my project. When I run the project for the first time(npm run dev), all the styles are applied as well, but if I make a change in my code and re-render it, the styles no longer work.
There is my code here:
"use client";
import React from "react";
import Image from "next/image";
import { BannerWrapper, ImageBannerWrapper, BannerTitle } from "./style";
export default function Banner() {
return (
<>
<ImageBannerWrapper className="absolute flex">
<Image
src="/images/banner/Mask-banner.png"
height={709}
width={747}
alt="banner"
/>
<BannerTitle className="font-primary text-9xl text-white text-left font-normal">
<span className="font-primary text-9xl text-white text-left font-semibold">
Let us guide you to the best choice.
</span>
</BannerTitle>
</ImageBannerWrapper>
<BannerWrapper className="flex items-center bg-default -mt-16" />
</>
);
}
答案1
得分: 2
我在NextJs的文档中找到了我的问题的答案。
由于我正在使用styled-component,我应该按照以下三个步骤配置CSS-in-JS:
- 创建一个样式注册表来收集所有渲染中的CSS规则。
- 使用新的useServerInsertedHTML hook在可能使用这些规则的任何内容之前注入规则。
- 创建一个客户端组件,在初始服务器端渲染期间将您的应用程序包装在样式注册表中。
创建一个新的注册表:
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
export default function StyledJsxRegistry({
children,
}: {
children: React.ReactNode
}) {
// 仅在懒惰的初始状态下创建样式表
// x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
const [jsxStyleRegistry] = useState(() => createStyleRegistry())
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>;
})
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}
然后,将您的根布局包装在注册表中:
import StyledJsxRegistry from './registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
英文:
I found the answer to my question in the documentation of NextJs.
Since I am using styled-component, I should be Configuring CSS-in-JS as a three-step:
> - A style registry to collect all CSS rules in a render.
> - The new useServerInsertedHTML hook to inject rules before any content that might use them.
> - A Client Component that wraps your app with the style registry during initial server-side rendering.
create a new registry:
'use client'
import React, { useState } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleRegistry, createStyleRegistry } from 'styled-jsx'
export default function StyledJsxRegistry({
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 [jsxStyleRegistry] = useState(() => createStyleRegistry())
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>
})
return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>
}
Then, wrap your root layout with the registry:
import StyledJsxRegistry from './registry'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<StyledJsxRegistry>{children}</StyledJsxRegistry>
</body>
</html>
)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论