来自不同组件的 React + Material-UI 样式类在静态服务时发生冲突

Posted

技术标签:

【中文标题】来自不同组件的 React + Material-UI 样式类在静态服务时发生冲突【英文标题】:React + Material-UI style classes from different components conflict when served statically 【发布时间】:2019-10-30 08:30:15 【问题描述】:

问题:当重新渲染组件时,应用于由 Material-UI / JSS 生成的类名的样式会错误地更改。

设置:我正在提供一个使用 Material-UI jss 样式和 Rails 后端的 React 应用程序(使用 create-react-app 构建)。我不确定 Rails 部分的相关性如何,因为当我直接在本地机器上打开 build/index.html 文件时也会发生同样的事情——Rails 后端处理根请求以提供静态客户端文件,如 here 所示.无论哪种情况,静态构建都是使用npm run build 创建的,它运行react-scripts build(来自create-react-app)。

问题示例:我有一个<img> 元素,它被赋予className: classes.logo。构建时,classes.logo"jss3",它采用以下正确的 CSS:

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

看起来像这样——<img> 组件位于应用标题的左上角。

我“继续作为客人”,并呈现新组件。但请注意徽标图像,它现在具有新样式:

发生了什么? <img> 组件现在显示以下样式:

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

这个 css 来自不同组件的完全不同的样式对象:

// FileEntry.js

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

从日志中,我确定AppHeader.js 中的classes.logoFileList.js 中的classes.fileEntry 都被命名为"jss3"。这就解释了为什么样式发生了变化——渲染了一个新组件 (<FileEntry),它覆盖了 "jss3" 类样式。

因此,目前的根本问题是:为什么两个样式元素的名称相互冲突 "jss3"?如何使用静态前端应用程序避免这种情况? (当我按照上面博客文章中的说明部署到 Heroku 时,也会出现此问题。)我希望得到一个仍然允许我从单个运行实例托管客户端和后端的答案,就像我在这里所做的那样,但如果另一个部署设置是最好的答案,那么我很想了解如何+为什么。

【问题讨论】:

【参考方案1】:

这个问题与使用两个不同版本的类名生成器有关。有很多方法可以做到这一点;在我的情况下,我将旧版本的 material-ui/core/styles#withStyles 与新版本的 material-ui/styles#makeStyles 混合在一起,因为我正在重构类组件以使用钩子。通过删除旧的core/styles#withStyles 的使用,我解决了这个问题。

发生的情况是两个样式类名生成器彼此不了解,并使用简单索引创建类名(例如jss3)。至少,他们在生产版本中这样做,似乎在开发版本中使用了更冗长的基于组件名称的类名,这解释了为什么我只在静态托管时看到它。

由于 FileEntry 组件直到登录才呈现,所以 jss3 类名直到登录操作之后才由第二个类名生成器生成,此时 jss3 类被赋予更新的样式,并且浏览器将其应用到现有的jss3 元素上。

一些变通解决方案涉及强制两者使用相同的 Jss 提供程序,但首先不使用类名生成器的独立调用是一个更彻底且得到良好支持的解决方案。

此处记录了类似的问题:

https://github.com/mui-org/material-ui/issues/8223 https://github.com/mui-org/material-ui/issues/11628

【讨论】:

【参考方案2】:

我在迁移到新的 material-ui 版本 (5) 后遇到了这个问题。

如果您有同样的问题,这应该会对您有所帮助

https://mui.com/guides/migration-v4/#migrate-from-jss https://github.com/mui-org/material-ui/blob/master/packages/mui-codemod/README.md#jss-to-styled

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review

以上是关于来自不同组件的 React + Material-UI 样式类在静态服务时发生冲突的主要内容,如果未能解决你的问题,请参考以下文章

酶不模拟 React Material-UI v1 上的更改事件 - 选择组件

Material Design Components React 风格按钮

React + Webpack + Material UI 样式在生产中中断

React + Material-UI |如何创建水平滚动卡片?

React Material Design:在类组件中使用带有 redux 的 React Material Design 自定义样式

React & Material-UI 分页 - 将 Material-UI 的组件连接到 React-Router