简体   繁体   中英

Next.Js React app with styled components. Warning: Prop `className` did not match. Server: "x" Client: "y"

In my NextJS React app when i change something in the code, the HMR works and shows the correct update but if I refresh the page, this error comes up again. This happens on dev mode. Noticed where are a lot of topics with this error, tried all day different configuration setups with no effort.

Please help me to get rid of the error.

Error:

Warning: Prop className did not match. Server: "sc-cBoprd hjrjKw" Client: "sc-iCoHVE daxLeG"

Using "babel-plugin-styled-components": "1.11.1"

Files that can be related to the issue:

_App.tsx

function MyApp({ Component, pageProps, mainController }) {
  return (
    <ConfigurationProvider configuration={configuration}>
        <ThemeProvider theme={mainController.getTheme()}>
          <Normalize />
          <Font />
          <Component {...pageProps} controller={mainController} />
        </ThemeProvider>
    </ConfigurationProvider>
  );
}

export default appControllerContext(MyApp);

_document.tsx

import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  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()
    }
  }
}

.babelrc

{
  "presets": [
    "next/babel"
  ],
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "ssr": true,
        "displayName": true,
        "preprocess": false
      }
    ]
  ]
}

This error means that something on the server is different from the Client. This can happen if the client does a re-render.

Styled Components use a random id on React elements, and when these elements get re-rendered they get a new random id on the client.

So the solution here is to get the styling exclusively from the server.

from the docs:

Basically you need to add a custom pages/_document.js (if you don't have one). Then copy the logic for styled-components to inject the server side rendered styles into the <head>

To solve this issue is you need something like this in your Document component:

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const sheet = new ServerStyleSheet();
    const page = renderPage((App) => (props) =>
      sheet.collectStyles(<App {...props} />)
    );
    const styleTags = sheet.getStyleElement();
    return { ...page, styleTags };
  }
  ...
  render() { ..}
}

The final step (if the error persists) is to delete the cache: delete the .next folder and restart the server

The full example code from Next documentation is here

I too had this issue and clearing my cache/restarting my dev server seems to have fix the issue so far.

Finally the one and only solution that worked was to rename .babelrc.json to babel.config.json. If someone still getting this error here i leave reference how to fix that solution

What worked for me was:

  • Create a .babelrc (on the root).

  • inside the .babelrc:

    { "presets": ["next/babel"], "plugins": [["styled-components", { "ssr": true }]] }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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