17

I use this code to margin my Button from top:

const makeTopMargin = (elem) => {
    return styled(elem)`
        && {
            margin-top: 1em !important;
        }
    `;
}

const MarginButton = makeTopMargin(Button);

and whenever i use MarginButton node, I get this error: Warning: PropclassNamedid not match. Server: "ui icon left labeled button sc-bwzfXH MjXOI" Client: "ui icon left labeled button sc-bdVaJa fKCkqX"

You can see this produced here.

What should I do?

mikemaccana
  • 81,787
  • 73
  • 317
  • 396

6 Answers6

12

You should install the babel plugin for styled-components and enable the plugin in your .babelrc

npm install --save-dev babel-plugin-styled-components

.babelrc

{
  "plugins": [
    [
      "babel-plugin-styled-components"
    ]
  ]
}
Sergei Basharov
  • 43,294
  • 56
  • 177
  • 295
Mikhail Sidorov
  • 864
  • 7
  • 14
12

This warning was fixed for me by adding an .babelrc file in the project main folder, with the following content:

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

See following link for an example: https://github.com/nblthree/nextjs-with-material-ui-and-styled-components/blob/master/.babelrc

C. Molendijk
  • 1,481
  • 1
  • 19
  • 28
2

PropType errors are runtime errors that will let you know that the data expected being passed to a prop is not what is expected. It looks like the className prop that is being set on your component is not the same when the component is rendered on the server and when it is then rendered in the client's DOM.

Since it looks like you are using server side rendering, you need to make sure that your class names are deterministic. That error is showing you the class that is being created by your styled-components library on the server and how it is different from the DOM. For libraries that do not normally have deterministic class names, you need to look at advanced configurations. Take a look at the styled-components documentation regarding specificity as it pertains to SSR.

brianespinosa
  • 2,232
  • 10
  • 18
2

Styled components server side rendering

Server Side Rendering styled-components supports concurrent server side rendering, with stylesheet rehydration. The basic idea is that everytime you render your app on the server, you can create a ServerStyleSheet and add a provider to your React tree, that accepts styles via a context API.

This doesn't interfere with global styles, such as keyframes or createGlobalStyle and allows you to use styled-components with React DOM's various SSR APIs.


import { renderToString } from 'react-dom/server'
import { ServerStyleSheet } from 'styled-components'

const sheet = new ServerStyleSheet()
try {
  const html = renderToString(sheet.collectStyles(<YourApp />))
  const styleTags = sheet.getStyleTags() // or sheet.getStyleElement();
} catch (error) {
  // handle error
  console.error(error)
} finally {
  sheet.seal()
}


import { renderToString } from 'react-dom/server'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'

const sheet = new ServerStyleSheet()
try {
  const html = renderToString(
    <StyleSheetManager sheet={sheet.instance}>
      <YourApp />
    </StyleSheetManager>
  )
  const styleTags = sheet.getStyleTags() // or sheet.getStyleElement();
} catch (error) {
  // handle error
  console.error(error)
} finally {
  sheet.seal()
}

In my case as im using nextjs

import Document, { Head, Main, NextScript } from "next/document";
import { ServerStyleSheet } from "styled-components";

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() {
    return (
      <html>
        <Head>{this.props.styleTags}</Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

Ahmed Younes
  • 494
  • 5
  • 12
  • I have tried to add styled-components to my Next.js project. It still doesn't work. My issue is that when I reload the page deployed by npm run dev, it throws the error of server not matching the styles at the client end. I have even used the babel-plugin-styled-component plugin. Nothing seems to be working. Can you suggest something? Thanks! – nwillo Jun 19 '20 at 14:42
2

//1.  I got an error when using material-ui with Next.js 


/********************************************* */

//2.  The code I imported was like this  : 


const useStyles = makeStyles({
    root: {     //  root must change 
        width: 100 ,
    }
});

const Footer = () => {
    const classes = useStyles();

    return (
        <div className={classes.root} > { /*  root must change */}
            <p> footer copyright @2021 </p>
        </div>
    )

}
export default Footer;


/********************************************* */

//3. I changed the code like this :


const useStyles = makeStyles({
    footer: {   //  changed here to footer
        width: "100%",
        backgroundColor: "blue !important"
    }
});

const Footer = () => {
    const classes = useStyles();

    return (
        <div className={classes.footer} > { /*  changed here to footer */}
            <p> footer copyright @2021 </p>
        </div>
    )

}
export default Footer;



// I hope it works
1

I attempted to follow the Styled-Components documentation, but it didn't work for me. I found another syntax for the .babelrc file:

// // This doesn´t work from styled-components DOCS
// {
//   "plugins": [
//     [
//       "babel-plugin-styled-components",
//       {
//         "ssr": false
//       }
//     ]
//   ]
// }


// This works!
{
  "presets": ["next/babel"],
  "plugins": [["styled-components", { "ssr": true }]]
}
Ian Campbell
  • 19,690
  • 9
  • 20
  • 44