React + Material-UI style classes from different components conflict when served statically
Asked Answered
I

2

9

Issue: styles applied to class names generated by Material-UI / JSS are incorrectly changing when components are re-rendered.

Setup: I'm serving a React app (built with create-react-app) that uses Material-UI jss styling and a Rails back end. I'm not sure how relevant the Rails part is since the same thing happens when I open the build/index.html file directly on my local machine -- the Rails back end handles the root request to serve the static client files as presented here. In either case, the static build is created using npm run build, which runs react-scripts build (from create-react-app).

Example of the issue: I have an <img> element which is given className: {classes.logo}. When built, classes.logo is "jss3", which takes on the following correct CSS:

.jss3 {
    height: 50px;
    position: relative;
    // [...more]
}

This looks like this -- the <img> component is at the top left in the app header.

enter image description here

I "continue as guest", and new components are rendered. But notice the logo image, which now has new styling:

enter image description here

What happened? The <img> component now shows the following styling:

.jss3 {
    height: 2em;
    padding: 7px;
    overflow: scroll;
    position: relative;
}

This css comes from an entirely different style object from a different component:

// FileEntry.js

  fileEntry: {
    position: 'relative',
    padding: '7px',
    height: '2em',
    overflow: 'scroll',
  },

From logs, I've determined that both classes.logo in AppHeader.js and classes.fileEntry from FileList.js are given the name "jss3". So that explains why the styles changed -- a new component (<FileEntry) was rendered and it overwrote the "jss3" class styles.

So the root question at the moment is: why are both style elements given the conflicting name "jss3"? How can I avoid this with a static front-end app? (The issue also occurs when I follow the instructions from the blog post above to deploy to heroku.) I'd love an answer that still allowed me to host both client and back-end from a single running instance as I'm doing here, but if another deployment setup is the best answer then I'd love to learn how + why.

Index answered 16/6, 2019 at 14:6 Comment(0)
I
11

The issue is related to using two different versions of a class name generator. Many ways to do this; in my case I was mixing an older version of material-ui/core/styles#withStyles with a newer material-ui/styles#makeStyles as I was refactoring class components to use hooks. By removing usage of the older core/styles#withStyles, I fixed the issue.

What happens is the two style classname generators don't know about each other, and create class names with simple indexes (e.g. jss3). At least, they do this for production builds, it seems there use more verbose component-name-based class names in dev builds, which explains why I was only seeing it when hosting statically.

Since the FileEntry component was not rendered until login, the jss3 class name was not generated by the second class name generator until after the login action, at which point the jss3 class was given updated styling, and the browser applied it to the existing jss3 elements as it is meant to do.

Some workaround solutions involved forcing both to use the same Jss Provider, but not using independent invocations of class name generators in the first place was a more thorough and well-supported solution.

Similar issues are documented here:

Index answered 18/6, 2019 at 15:52 Comment(0)
C
1

I've faced this problem after migrating to the new material-ui version (5).

This should help you if you have the same issue

Cleptomania answered 17/11, 2021 at 9:37 Comment(2)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Malaria
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewNiobe

© 2022 - 2024 — McMap. All rights reserved.