简体   繁体   English

Next.js 13 with Ant 设计5:组件和页面在Styles加载前渲染,导致跳转

[英]Next.js 13 with Ant Design 5: Components and Pages Render Before Styles Load, Causing Jump

I followed the antd and nextjs doc to config the project.我按照 antd 和 nextjs 文档来配置项目。

Added this code into the ./scripts/genAntdCss.tsx file:将此代码添加到./scripts/genAntdCss.tsx文件中:

import { extractStyle } from '@ant-design/static-style-extract';
import fs from 'fs';
const outputPath = './public/antd.min.css';
const css = extractStyle();
fs.writeFileSync(outputPath, css);

and this is App.tsx file:这是 App.tsx 文件:

import { StyleProvider } from '@ant-design/cssinjs';
import type { AppProps } from 'next/app';
import '../public/antd.min.css';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <StyleProvider hashPriority='high'>
      <Component {...pageProps} />
    </StyleProvider>
  );
}

these commands added to package.json file:这些命令添加到package.json文件中:

"predev": "ts-node --project ./tsconfig.node.json ./scripts/genAntdCss.tsx",
"prebuild": "ts-node --project ./tsconfig.node.json ./scripts/genAntdCss.tsx"

Do you have any idea to fix this?你有什么办法解决这个问题吗?

I found a way to solve it but I had to use the new "app", "layout" and "use client" features of NextJS 13. I hope it helps someone:我找到了解决它的方法,但我不得不使用 NextJS 13 的新“应用程序”、“布局”和“使用客户端”功能。我希望它能帮助别人:

I answered here but I will copy and paste it here again to avoid you from opening it: https://github.com/ant-design/ant-design/issues/38555#issuecomment-1535788843我在这里回答但我会再次复制并粘贴在这里以避免您打开它: https://github.com/ant-design/ant-design/issues/38555#issuecomment-1535788843

Well, I've found the link below where @chunsch added an example in the NextJS repo https://github.com/vercel/next.js/pull/44015/files好吧,我找到了下面的链接,@chunsch 在 NextJS 存储库中添加了一个示例https://github.com/vercel/next.js/pull/44015/files

Also, @kiner-tang helped us to fix the layout shift while loading https://github.com/ant-design/ant-design/issues/42275#issuecomment-1555805914另外,@kiner-tang 帮助我们解决了加载时布局偏移问题https://github.com/ant-design/ant-design/issues/42275#issuecomment-1555805914

It's possible but we need to do some weird stuff with the new cssinjs AntD 5 feature and with the NextJS 13 app and layout features.这是可能的,但我们需要使用新的cssinjs AntD 5 功能以及 NextJS 13 应用程序和布局功能做一些奇怪的事情。 I would like to avoid using that but it's the way I found.我想避免使用它,但这是我发现的方式。 Sorry.对不起。

I basically had to use the new "app" directory (experimental feature yet), create a root layout (layouts are one of the new features too), and create a RootStyleRegistry component specifying that it should be a client component with the 'use client' directive.我基本上必须使用新的“app”目录(尚处于试验阶段),创建一个根布局(布局也是新功能之一),并创建一个 RootStyleRegistry 组件,指定它应该是一个带有“使用客户端”的客户端组件'指令。 Additionally, if you use the Layout component, you should specify the hasSider={true} prop to avoid a shifting effect in the first render.此外,如果您使用Layout组件,则应指定hasSider={true}属性以避免在第一次渲染时出现偏移效果。

Install @ant-design/cssinjs if you don't have it installed如果没有安装@ant-design/cssinjs,请安装

  1. Create the RootStyleRegistry component创建RootStyleRegistry组件
// located at src/modules/shared/components/root-style-registry/index.tsx in my case

'use client'
import { useState, type PropsWithChildren } from 'react'
import { useServerInsertedHTML } from 'next/navigation'
import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs'

export const RootStyleRegistry = ({ children }: PropsWithChildren) => {
  const [cache] = useState(() => createCache())

  useServerInsertedHTML(() => {
    return (
      <script
        dangerouslySetInnerHTML={{
          __html: `</script>${extractStyle(cache)}<script>`,
        }}
      />
    )
  })

  return <StyleProvider cache={cache}>{children}</StyleProvider>
}

  1. Create the layout for the root page为根页面创建布局
// src/app/layout.tsx
import type { PropsWithChildren } from 'react'
import { RootStyleRegistry } from '../modules/shared/components/root-style-registry'

export default function RootLayout({ children }: PropsWithChildren) {
  return (
    <html lang="es">
      <head />
      <body>
        <RootStyleRegistry>{children}</RootStyleRegistry>
      </body>
    </html>
  )
};

  1. Create your page component using the 'use client' directive.使用“使用客户端”指令创建您的页面组件。 Remember you must name it 'page' now (like an index file inside a folder)请记住,您现在必须将其命名为“页面”(就像文件夹中的索引文件一样)
// src/app/page.tsx

'use client'
import React, { Button, Card, Space, Typography } from 'antd'

export default function Home() {
  return  <Button type="primary">Ant Design Button</Button>
}

  1. If you use the Layout component and you are experimenting a navbar shift while loading, you should explicitly specify the 'hasSider' prop如果您使用Layout组件并且在加载时尝试导航栏移动,则应明确指定 'hasSider' 道具
// src/app/components/layout.tsx

export function MyLayout({ children }) {
  return (
    <Layout hasSider>
      <Sider>
        {children}
      </Sider>
    </Layout>
  )
}

It worked for me following the instructions in the AntD docs, which it looks like you're doing.它按照 AntD 文档中的说明对我有用,看起来您正在这样做。

https://ant.design/docs/react/customize-theme#server-side-render-ssr https://ant.design/docs/react/customize-theme#server-side-render-ssr

Make sure you are installing the necessary dependencies确保您正在安装必要的依赖项

npm install ts-node tslib --save-dev

and adding the tsconfig.node.json , you didn't specify that you did these two steps.并添加tsconfig.node.json ,您没有指定您执行了这两个步骤。

https://mobile.ant.design/guide/ssr https://mobile.ant.design/guide/ssr

// next.config.js
const nextConfig = {
  transpilePackages: ['antd-mobile'], // or ['antd']
};

module.exports = nextConfig;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM