警告:Prop `className` 与 Next.JS 站点中的样式组件不匹配

jon*_*bbs 9 reactjs styled-components next.js

我在 Stack Overflow 上搜索了类似的问题,但答案要么涉及旧版本,要么与我的情况无关。

对于使用样式组件的页面上的第一个组件,我收到上述错误。如果我删除该组件,我会收到下一个组件的错误,依此类推,因此我假设水合过程存在问题,并且每个 className 都会发生这种情况。

我有一个_document.tsx文件,它扩展了 Document 类并具有以下 getInitialProps 函数

static async getInitialProps (ctx) {

    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {

        ctx.renderPage = () =>
            originalRenderPage({
            enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
        })

        const initialProps = await Document.getInitialProps(ctx)
        
        return {
            ...initialProps,
            styles: (
                <>
                    {initialProps.styles}
                    {sheet.getStyleElement()}
                </>
            )
        }
        
    } finally {
        sheet.seal()
    }
    
}
Run Code Online (Sandbox Code Playgroud)

我的预感是这与这段代码有关,因为在我升级到 Typescript(并且必须更改我的 _app.tsx 文件)之前,我没有收到此错误,但我不知道如何修复它。

任何帮助将不胜感激。

jul*_*ves 10

尝试安装babel-plugin-styled-components,然后.babelrc使用以下配置将文件添加到项目的根目录。这确保了再水化过程中不会发生类别生成的不匹配。

{
    "presets": ["next/babel"],
    "plugins": [["styled-components", { "ssr": true }]]
}
Run Code Online (Sandbox Code Playgroud)

来自babel-plugin-styled-components的文档

通过向每个样式组件添加唯一标识符,该插件可以避免由于客户端和服务器上的类生成不同而导致的校验和不匹配。如果您不使用此插件并尝试在服务器端渲染样式组件,React 将在补水期间发出 HTML 属性不匹配警告。

  • 只是为了添加,我添加了一个 .babelrc 文件,而不是 Babel.config.json (2认同)
  • @decryptingfuture 看起来 Next.js 团队计划将此插件移植到 SWC 编译器:https://github.com/vercel/next.js/issues/30802。在那之前我猜你已经被 Babel 困住了。 (2认同)

Sha*_*ddy 9

Next.js 自 . 以来添加了对样式组件的支持v12.0.1。您唯一需要做的就是修改该next.config.js文件。它应该如下所示。

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  // This is the property you need to add
  compiler: {
    // ssr and displayName are configured by default
    styledComponents: true,
  },
};

module.exports = nextConfig;
Run Code Online (Sandbox Code Playgroud)

来源:Next.js 文档

  • 您可能需要指出,此配置适用于 Next.js 编译器 (SWC),而不是 Babel。 (2认同)
  • 我没有使用 babel,而是 SWC。我按照其他 stackoverflow 答案中提到的方式添加了“_document.js”,但问题仍然存在,直到我不得不使用此解决方案修改“next.config.js”。谢谢它对我有用。 (2认同)