【问题标题】:React CSS class gets override automatically on production serverReact CSS 类在生产服务器上自动覆盖
【发布时间】:2021-04-03 02:52:53
【问题描述】:

我在我的 React 项目中遇到了一个奇怪的 CSS 问题。 JSX <div> 的特定部分应用了一个类,并在项目的主 .css 文件中添加了一些样式属性。在本地开发中,一切正常,但一旦创建构建并将其上传到生产服务器,JSX <div> CSS 类的特定部分就会发生变化,并且样式会失真。

例子:

原始 JSX

import React, { useEffect, useState, useContext } from "react";
import Tooltip from "@material-ui/core/Tooltip";
import { withStyles, makeStyles } from "@material-ui/core/styles";
import Slider from "@material-ui/core/Slider";

const useStyles = makeStyles((theme) => ({
  root: {
    width: 450,
  },
  margin: {
    height: 100,
  },
}));

const PrettoSlider = withStyles({
  root: {
    color: "red",
    height: 8,
  },
  thumb: {
    height: 24,
    width: 24,
    backgroundColor: "#fff",
    border: "2px solid currentColor",
    marginTop: -8,
    marginLeft: -12,
    "&:focus,&:hover,&$active": {
      boxShadow: "inherit",
      border: "2px solid #fff407 !important",
    },
  },
  active: {
    backgroundColor: "#fff407",
  },
})(Slider);

const CustomizedSlider = ({
  id,
  abbr,
  type,
  minElig,
  maxElig,
}) => {

  useEffect(() => {
    setValue(sliderPreviousValue);
  }, [sliderPreviousValue]);


  const classes = useStyles();
  return (
    <>
      <div className={classes.root}>
        {type === "intervention" ? (
          <ProgressBar max={maxElig} value={sliderValue} />
        ) : null}

        {renderSlider}
      </div>
    </>
  );
};

原始 DOM:

<div class="diabMetr clearfix">
   <span class="diabLabl">Diabetes</span>
   <div class="makeStyles-root-1">
      <span class="MuiSlider-root WithStyles(ForwardRef(Slider))-root-3 MuiSlider-colorPrimary"><span class="MuiSlider-rail WithStyles(ForwardRef(Slider))-rail-8"></span><span class="MuiSlider-track WithStyles(ForwardRef(Slider))-track-7" style="left: 0%; width: 83.3333%;"></span><input type="hidden" value="200"><span class="MuiSlider-thumb WithStyles(ForwardRef(Slider))-thumb-4 MuiSlider-thumbColorPrimary PrivateValueLabel-open-12 PrivateValueLabel-thumb-11" tabindex="0" role="slider" data-index="0" aria-label="pretto slider" aria-orientation="horizontal" aria-valuemax="240" aria-valuemin="0" aria-valuenow="200" style="left: 83.3333%;"><span class="PrivateValueLabel-offset-13 MuiSlider-valueLabel WithStyles(ForwardRef(Slider))-valueLabel-6"><span class="PrivateValueLabel-circle-14"><span class="PrivateValueLabel-label-15">200</span></span></span></span></span>
      <div class="valueOuter clearfix"><label class="valueLeft">0</label><label class="valueRight">240</label></div>
   </div>
</div>

这个 JSX 的 CSS 是:

.diabMetr {
        padding-top: 10px;
        span.diabLabl {
          display: inline-block;
          width: 200px;
          text-align: left;
          font-size: 12px;
          line-height: 30px;
          text-align: right;
          @include respond-to(media-xl) {
            width: 120px;
          }
        }
        span.MuiSlider-root {
          width: 100%;
          padding: 0;
          height: 0px;

          .MuiSlider-rail {
            height: 30px;
            border-radius: 15px;
            background: #e8e8e8;
            opacity: 1;
          }
          .MuiSlider-track {
            height: 30px;
            background: #88d479;
            border-radius: 15px;
          }
          .MuiSlider-thumb {
            z-index: 12;
            width: 35px;
            height: 35px;
            border-radius: 50%;
            margin-left: -17px;
            border: #88d479 solid 2px;
            margin-top: -3px;
          }
          .MuiSlider-markLabel.MuiSlider-markLabelActive:last-child() {
            right: 0 !important;
          }
        }
      }

.makeStyles-root-1 {
  width: calc(100% - 220px) !important;
  float: right;
  margin-top: -22px;
}

构建后的DOM变化并上传到服务器:

<div class="diabMetr clearfix">
   <span class="diabLabl">Diabetes</span>
   <div class="jss16">
      <span class="MuiSlider-root jss18 MuiSlider-colorPrimary"><span class="MuiSlider-rail jss23"></span><span class="MuiSlider-track jss22" style="left: 0%; width: 83.3333%;"></span><input type="hidden" value="200"><span class="MuiSlider-thumb jss19 MuiSlider-thumbColorPrimary jss27 jss26" tabindex="0" role="slider" data-index="0" aria-label="pretto slider" aria-orientation="horizontal" aria-valuemax="240" aria-valuemin="0" aria-valuenow="200" style="left: 83.3333%;"><span class="jss28 MuiSlider-valueLabel jss21"><span class="jss29"><span class="jss30">200</span></span></span></span></span>
      <div class="valueOuter clearfix"><label class="valueLeft">0</label><label class="valueRight">240</label></div>
   </div>
</div>

.jss16 类的 CSS 是:

.jss16 {
    width: 450px;
}

需要注意的问题 当构建上传到服务器并且 CSS 相应更改时,只有类 .makeStyles-root-1 被一些随机类 .jss16 替换,JSX 的其余部分保持不变。我尝试在代码中到处搜索类.jss16,但没有找到。此外,在 localhost 上一切正常。

我尝试将 CSS 属性添加到 .jss16,如下所示:

.jss16 {
  width: 450px;
  width: calc(100% - 220px) !important;
  margin-top: -22px;
  float: right;
}

然后重新启动上传过程,但随后将替换为 .jss42 之类的另一个类,而不是 .jss16。这会不断重复,并且不适用于创建的任何新版本。

我还尝试了以下 CSS:

.diabMetr + span + div {
  width: 450px;
  width: calc(100% - 220px) !important;
  margin-top: -22px;
  float: right;
},

但这也没有帮助。应用的样式仍然失真(不正确,与 localhost 不同)。

我花了几个小时寻找这个但徒劳无功。如果有人可以帮助我理解此错误并解决相同的问题,将不胜感激。提前致谢!

【问题讨论】:

  • 我会继续研究这个,但它似乎类似于捆绑 webpack 构建时 styled-components 所做的事情。它通过设计将任何类名转换为随机生成的类名。
  • 您向我们展示的不是 jsx,而是生成的 DOM(这有点误导)
  • @MihályiZoltán 我忘了补充。现已更新

标签: javascript html css reactjs material-ui


【解决方案1】:

这段代码有很多问题。首先在jsx CSS 类中给出className,正如@Max 在他/她的回答中提到的那样。
另一个问题是@material-uimakeStyle 不能以这种方式工作。 makeStyle 中的 classNames 在构建阶段更改为随机名称。这恰好保持 classNames 的唯一性,这是 @material-ui 的功能。我建议您阅读this @matrial-ui's documentation 关于makeStyles。并提供here 代码示例。

要使用 makeStyles 类,您必须将其挂接到您的组件中。

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles({
  root: {
    backgroundColor: 'red',
    color: props => props.color,
  },
});

export default function MyComponent(props) {
  const classes = useStyles(props);
  return (
    <div className={classes.root}>
      Lorem iosum poder
    </div>
  );
}

更新

根据您的jsx 代码,在useStyles 对象中添加您在css 类.makeStyles-root-1 中添加的样式。它会将样式添加到元素中。
useStyles 中添加这些 CSS 样式后,此对象将如下所示:-


const useStyles = makeStyles((theme) => ({
  root: {
    width: 'calc(100% - 220px) !important',
    float: 'right',
    marginTop: '-22px'

  },
  margin: {
    height: 100,
  },
}));

root 类将包含这些样式,并且将在不单独提供 CSS 文件的样式的情况下应用它。

【讨论】:

  • 我用 JSX 而不是 DOM 更新了我的代码。 &lt;div className={classes.root}&gt; 实际上是用 DOM 中的随机 className 转换的。
  • 是的.. 这发生在构建时的幕后。现在是你在.makeStyles-root-1 类中应用的样式,现在你可以在root 键的useStyles 对象中添加这些样式。我将在几分钟内更新答案。
  • 还有一个小帮助。如果我将属性 margin 从 CSS root: { width: 'calc(100% - 220px) !important', float: 'right', marginTop: '-22px' }, margin: { height: 100, }, 传递给组件 &lt;ProgressBar max={maxElig} value={sliderValue} clsmargn={classes.margin}/&gt;,它会在 DOM 中创建一个新类,例如:&lt;div class="makeStyles-root-1"&gt; &lt;div class="makeStyles-root-2"&gt; &lt;span class="MuiSlider-root &gt;.....&lt;/span&gt; &lt;/div&gt; &lt;/div&gt;。你能帮忙解释一下这种行为吗?
  • 是的。这就是@material-ui 编译的工作原理。它创建新的随机类名,以便类在每个文件中保持唯一。假设您在Component AComponentB 中创建了一个root 类,但是您为两个组件中的根类赋予了不同的样式。如果它不创建一个新类,那么两种样式都会发生冲突,结果将不是预期的。因此,它为每个文件创建不同且唯一的类名,或者更好地为每个 makeStyls 使用创建一个。
【解决方案2】:

解决方案

我不确定是哪个组件创建了带有“jss16”类的 div,假设它是ExternalComponent

您应该添加一个自定义类名(假设 ExternalComponent 正确处理):

<ExternalComponent className="myclass">
   ...
</ExternalComponent>

这将创建一个这样的 DOM:

<div class="jss16 myclass">
    ...
</div>

你可以为myclass创建css:

.myclass {
  width: calc(100% - 220px) !important;
  float: right;
  margin-top: -22px;
}

说明

ExternalComponent使用jss动态生成css类,所以不能依赖动态生成的类名。在大多数情况下,具有自定义类的组件应将 props.className 附加到生成的 jss 中,如下所示:

return (
    <div className={jssClassname + props.className ? ' ' + props.className : ''}>
        {children}
    </div>
);

【讨论】:

    【解决方案3】:

    我无法重现错误,因为我有一些语法问题,所以我想知道如果修复这些问题,构建会正常运行:

    • 将关闭/ 添加到input
    • 使用对象编写样式,例如style={{left: '0%', width: '83.3333%'}}
    • class 更新为className
    • tabindex 更新为tabIndex

    最后,如果这没有帮助,让你的 CSS 工作,即.diabMetr + span + div,将其重写为:

    .diabMetr &gt; span + div {}

    .diabMetr &gt; div {}

    现在,它没有选择子元素。

    【讨论】:

      猜你喜欢
      • 2020-07-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 2014-05-07
      • 2013-10-05
      • 2021-11-12
      • 2016-05-14
      相关资源
      最近更新 更多