styled-components在NextJS 13中未应用CSS。

huangapple go评论57阅读模式
英文:

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:

&quot;use client&quot;;
import React from &quot;react&quot;;
import Image from &quot;next/image&quot;;
import { BannerWrapper, ImageBannerWrapper, BannerTitle } from &quot;./style&quot;;

export default function Banner() {
  return (
    &lt;&gt;
      &lt;ImageBannerWrapper className=&quot;absolute flex&quot;&gt;
        &lt;Image
          src=&quot;/images/banner/Mask-banner.png&quot;
          height={709}
          width={747}
          alt=&quot;banner&quot;
        /&gt;
        &lt;BannerTitle className=&quot;font-primary text-9xl text-white text-left font-normal&quot;&gt;
          &lt;span className=&quot;font-primary text-9xl text-white text-left font-semibold&quot;&gt;
            Let us guide you to the best choice.
          &lt;/span&gt;
        &lt;/BannerTitle&gt;
      &lt;/ImageBannerWrapper&gt;
      &lt;BannerWrapper className=&quot;flex items-center bg-default -mt-16&quot; /&gt;
    &lt;/&gt;
  );
}

答案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:

&#39;use client&#39; 
import React, { useState } from &#39;react&#39;
import { useServerInsertedHTML } from &#39;next/navigation&#39;
import { StyleRegistry, createStyleRegistry } from &#39;styled-jsx&#39;
 
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(() =&gt; createStyleRegistry())
 
  useServerInsertedHTML(() =&gt; {
    const styles = jsxStyleRegistry.styles()
    jsxStyleRegistry.flush()
    return &lt;&gt;{styles}&lt;/&gt;
  })
 
  return &lt;StyleRegistry registry={jsxStyleRegistry}&gt;{children}&lt;/StyleRegistry&gt;
}

Then, wrap your root layout with the registry:

import StyledJsxRegistry from &#39;./registry&#39;
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    &lt;html&gt;
      &lt;body&gt;
        &lt;StyledJsxRegistry&gt;{children}&lt;/StyledJsxRegistry&gt;
      &lt;/body&gt;
    &lt;/html&gt;
  )
}

huangapple
  • 本文由 发表于 2023年7月24日 19:49:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76754190.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定