garronej / tss-react

✨ Dynamic CSS-in-TS solution, based on Emotion
https://tss-react.dev
MIT License
608 stars 37 forks source link

Warning: Prop `className` did not match. #87

Closed anjananair07 closed 2 years ago

anjananair07 commented 2 years ago

I'm having difficulty with differences between the client-side and server-side rendering of styles in Material-UI components due to classNames being assigned differently. Below is the error message I'm getting on the console after page load,

image

The versions I'm using are as follows,

"@emotion/cache": "^11.7.1", "@emotion/react": "^11.9.0", "@emotion/server": "^11.4.0", "@emotion/styled": "^11.8.1", "@mui/lab": "^5.0.0-alpha.81", "@mui/material": "^5.7.0", "react": "^17.0.2", "tss-react": "^3.6.2",

Please help me solve this issue.

garronej commented 2 years ago

Hi @anjananair07,
Unfortunately I can't help you with the amount of information you provided.
Do you confirm to have followed the specific instruction for integration with next:
https://docs.tss-react.dev/ssr/next.js
You can also have a look at the working example: https://github.com/garronej/tss-react/tree/main/src/test/apps/ssr

If you are still experiencing problem after that please submit a testable repo where I can reproduce the error.

Best regards

anjananair07 commented 2 years ago

Yes, I've followed all the instructions mentioned in the tss-react doc but still no luck.

Is there any way to disable/remove the class prepended to every classname (i.e. tss-5tf8fq-MuiHeaderComponent-backButton to just MuiHeaderComponent-backButton)?

I've added the component name to fix this issue as below but still, tss-5tf8fq is added at the beginning of the classname

const useStyles = makeStyles<
  StyleProps,
  | 'logo'
  | 'logoLink'
  | 'backButton'
  | 'slimToolbar'
  | 'navLinks'
  | 'progress'
  | 'profileButton'
>({ name: 'MuiHeaderComponent' })(
  (theme, { profileHeader, shopHeader }, classes) => ({
    appBar: {
      transition: 'background-color 0.5s ease',
    },
    toolbar: {
      display: 'flex',
      zIndex: zIndexes.header,
      color: theme.palette.common.white,
      padding: theme.spacing(0, 3),
      transition: 'height 0.2s linear',
      [theme.breakpoints.down('sm')]: {
      .......
garronej commented 2 years ago

Hi @anjananair07,
Ok, I think I got it, hold on.

garronej commented 2 years ago

It would be much easier if I could see your code, I understand that it's not open source and you can't just share the repo but reverse engineering what you are doing with the few clues you gave me is not an easy task.

What I can see is that on the server you have:

image

And on the client:

image

The number is a counter that is incremented each time makeStyles is invoked.

In my model I assumed that createMakeStyles would be called exactly once for the lifespan of the process and that makeStyles would be called a fix amount of time, usually n times, n being the number of components of your application.

Currently, it's not what's happening, it's maybe something related with hot reloading.

Any additional information would be much appreciated.

Sill investigating...

anjananair07 commented 2 years ago

Hi @garronej

I think the issue is with the third parameter (classes) being passed in the makeStyles. The warning is not appearing when I remove the class name that uses classes.

Please see the code below,

interface StyleProps {
  profileHeader: boolean
  shopHeader: boolean
}

const useStyles = makeStyles<
  StyleProps,
  | 'backButton'
>()((theme, { profileHeader, shopHeader }, classes) => ({
  backButton: {
    width: 48,
    height: 48,
    padding: 0,
    marginLeft: theme.spacing(-1),
    color: colors.primary.copper[1],
    '&:hover path': {
      stroke: colors.tints.blue[4],
    },
    '&:active path': {
      stroke: colors.tints.blue[6],
    },
  },
  darkTheme: {
    [`& .${classes.backButton}`]: {
      color: colors.primary.grey[0],
      '&:hover': {
        backgroundColor: theme.palette.common.white,
        borderColor: theme.palette.common.white,
        color: colors.tints.blue[4],
        textDecoration: 'none',
        '& path': {
          stroke: colors.tints.blue[4],
        },
      },
    },
  },
}))

interface Props {
    profileHeader?: boolean
    shopHeader?: boolean
}

const Header: FunctionComponent<Props> = ({
  profileHeader = false,
  shopHeader = false,
}) => {
  const { classes, cx } = useStyles({
    profileHeader,
    shopHeader,
  })

  return (
    <div className={className={classes.backButton}}>Hello</div>
  )
}

export default Header

Thank you.

garronej commented 2 years ago

Hi @anjananair07,
Thank you for the code snippet.
I have identified what is the source of the problem, it is indeed related to classes.
The problem is that the fix is very tricky to implement and I don't understand exactly how you end up in this situation.
Does your project contains 2000 component (2000 different call to makeStyles), if not, how comes, on the server makeStyles is invoked thousand of times.
What version of Next are you using?
It would really help me if you could come up with a repo where I can reproduce the problem.

If you can do that I will try to solve the issue in the best delay.
Otherwise I will wait and see if other peoples report the same issue.

Best regards,

anjananair07 commented 2 years ago

Hi @garronej

Thank you for your prompt reply!

There are around 300 components in my project and the issue occurred when we upgraded to MUI v5 and react-tss.

Versions used are, "next": "^12.1.6", "tss-react": "^3.6.2", "@mui/lab": "^5.0.0-alpha.81", "@mui/material": "^5.7.0",

garronej commented 2 years ago

Ok thank you,
I'll need a repoduction path.
Try to clone your project, remove the sensible part and share it with me?

garronej commented 2 years ago

Can you try with

"tss-react": "v3.7.0-beta.2"

And copy paste what you get in the log.

Thank you

anjananair07 commented 2 years ago

Sure @garronej

anjananair07 commented 2 years ago

Hi @garronej

Please find the screenshot of the Dev console below,

image

Thanks.

garronej commented 2 years ago

Thanks for the screen,
Interesting... 🤔
May I have the node log (the output of your terminal after running yarn dev).
Could you try building the app and see if you have the same problem in production (yarn build && yarn serve)?

Thank you

garronej commented 2 years ago

Could you try building the app and see if you have the same problem in production (yarn build && yarn serve)?

Before upgrading, please check if the issue is only in dev mode or if it happens in production as well.

Then you can try with:

"tss-react": "v3.7.0-beta.3"

It should fix the issue.

anjananair07 commented 2 years ago

The issue is only in dev mode and not in production.

Below is the o/p of terminal, image

Still see warning message after upgrading (v3.7.0-beta.3),

image

garronej commented 2 years ago

Thank you for the additional info but please please, would you share a reproducible repo.
I spent many hours already trying, unsuccessfully, to reproduce the behavior.
It's super hard to debug without knowing exactly what is going on.

garronej commented 2 years ago

Could you please try with?

        "next": "12.1.7-canary.4",
        "react": "18.1.0",
        "react-dom": "18.1.0",
       "tss-react": "3.6.2"
anjananair07 commented 2 years ago

Thank you so much for spending your time helping me!

The issue still persists with the version you have mentioned above :( Yes, I'll try to share a reproducible repo as soon as possible.

garronej commented 2 years ago

@anjananair07 you are welcome,
But you know, I am pretty sure your issue is legit bug on tss-react end, it had to be addressed, you are helping me as much as I am helping you.

Be sure that, one war on another, I will publish a patch that fixes the issue.
I just hope I'll find a way to fix it that is transparent for you.

arkaaaadiy commented 2 years ago

@garronej We faced the same problem after upgrading to mui 5, on the client the class is different from the server which is obtained from classes

garronej commented 2 years ago

Thanks for reporting @arkaaaadiy I will address the issue.

garronej commented 2 years ago

@anjananair07 @arkaaaadiy
I have published a new version 3.7.0 that addresses the isue you are facing.
Please update and refer to the documentation.

Be aware that you'll only need a uniqId where you uses nested selectors.

Best regards

anjananair07 commented 2 years ago

Works like a charm! Thank you so much @garronej