ant-design / antd-style

css-in-js library with antd v5 token system

Home Page:https://ant-design.github.io/antd-style/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

🧐[问题]在Nextjs13中按照文档中【SSR集成】中描述的方式使用,在通过createStyles写样式时会报错

ISproutNew opened this issue · comments

🧐 问题描述

在Next13通过App Router的方式创建的应用,按照文档说明创建了一个StyleRegistry组件并且在 app/layout.tsx中引入

import StyleRegistry from './StyleRegistry';

const RootLayout = ({ children }: PropsWithChildren) => (
  <html lang="en">
    <body>
      <StyleRegistry>{children}</StyleRegistry>
    </body>
  </html>
);

然后在 app/page.tsx文件中

import { createStyles } from "antd-style";

const useStyles = createStyles(({ css }) => {
	return {
		main: css`
			width: 100vw;
			height: 100vh;
		`,
	};
});

export default function Home() {
	const { styles } = useStyles();
	return <main className={styles.main}>my home</main>;
}

产生的报错内容如下:

Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component

在app/page.tsx文件的头部添加 "use client" 就不会报错了。

并且我尝试在其他路由页面例如: app/about/page.tsx 使用createStyles书写样式也会得到同样的报错(不添加"use client"的情况下)。

是我使用的方式不对吗?还是说必须要添加"use client" ,我理解如果要添加"use client"那就意味着整个应用都是客户端组件了🤔

💻 示例代码

src/lib/StyleRegistry.tsx

"use client";

import { StyleProvider, extractStaticStyle } from "antd-style";
import { useServerInsertedHTML } from "next/navigation";
import { PropsWithChildren, useRef } from "react";

const StyleRegistry = ({ children }: PropsWithChildren) => {
	const isInsert = useRef(false);

	useServerInsertedHTML(() => {
		// 避免多次渲染时重复插入样式
		// refs: https://github.com/vercel/next.js/discussions/49354#discussioncomment-6279917
		if (isInsert.current) return;

		isInsert.current = true;

		const styles = extractStaticStyle("").map(item => item.style);

		return <>{styles}</>;
	});

	return (
		<StyleProvider cache={extractStaticStyle.cache}>{children}</StyleProvider>
	);
};

export default StyleRegistry;

src/app/layout.tsx

import Layout from "@/components/Layout";
import StyledComponentsRegistry from "@/lib/StyleRegistry";
import { ThemeToken } from "@/types/theme";

declare module "antd-style" {
	export interface CustomToken extends ThemeToken {}
}

// Font files can be colocated inside of `app`

export default function RootLayout({
	children,
}: {
	children: React.ReactNode;
}) {
	return (
		<html>
			<body>
				<StyledComponentsRegistry>
					<Layout>{children}</Layout>
				</StyledComponentsRegistry>
			</body>
		</html>
	);
}

src/app/page.tsx

import { createStyles } from "antd-style";

const useStyles = createStyles(({ css }) => {
	return {
		main: css`
			width: 100vw;
			height: 100vh;
		`,
	};
});

export default function Home() {
	const { styles } = useStyles();
	return <main className={styles.main}>my home</main>;
}

🚑 其他信息

image

是我使用的方式不对吗?还是说必须要添加"use client" ,我理解如果要添加"use client"那就意味着整个应用都是客户端组件了🤔

目前 CSSinJS 都是客户端渲染,所以必须要加 'use client' 的