【问题标题】:CSS in JS, how to make props.className the priority classJS中的CSS,如何让props.className成为优先类
【发布时间】:2020-04-17 10:54:50
【问题描述】:

我们需要组件,其中作为 props 传递的类应该比默认类具有更高的优先级。

当将classes作为prop传递时,组件优先 在他自己的文件中创建的类。

Text.jsx

// this will be a component in another folder, it will be used in the whole app so it 
// should haveDYNAMIC styling
function Text(props) {
  const useStyles = makeStyles(theme => ({
    default: {
      fontSize: 18,
      color: "black"
    }
  }));

  const classes = useStyles();

  return (
    <div className={classNames(classes.default, props.className)}>
      {props.children}
    </div>
  );
}

App.jsx

function App() {
  const useStyles = makeStyles(theme => ({
    title: {
      fontSize: 80,
      color: "red"
    },
    notGoodPractice: {
      fontSize: "80px !important"
    }
  }));
  const classes = useStyles();

  return (
    <div className="App">
      <Text className={classes.title}>Text in here is 18px</Text>
      <Text className={classes.notGoodPractice}>
        Text in here is 80px
      </Text>
    </div>
  );
}

反应片段 => CodeSandBox

【问题讨论】:

  • CSS 没有“优先级”的概念。某些 CSS 选择器确实具有更高的优先级和选择性——但规则并不简单:tutorials.jenkov.com/css/precedence.html
  • 这在正常优先级中很容易,我只需在 .css 文件的开头编写默认类,并在其下编写所有其他类:,真正的问题在于 CSS IN JS
  • 这种方式很难做到,在 css 中它不掌握 classname 属性中的最后一个,当你定义 css 规则时,重要的是什么是最后一个。它与 spred 运算符或 Object.assign 不同。如果你想要的是将组件与样式解耦,然后注入样式以使其看起来像你想要的那样,我参考这篇文章:jobs.zalando.com/tech/blog/decoupled-styling-ui-components/…
  • 您是否尝试过使用像 className={${classes.default} ${props.className}} 这样的字符串文字。我现在无法测试这个。但据我所知,我遇到了同样的问题并像这样使用它。
  • @RenaldoBalaj 是的,我也这么认为。很好奇解决方法,希望你能找到答案。

标签: javascript reactjs react-native material-ui react-hooks


【解决方案1】:

您可以通过这种方式对作为 props 传递的类进行优先级排序。

请确保您没有在其上应用makeStyles,以便您可以在孩子中正确访问它们。

import React from "react";
import ReactDOM from "react-dom";
import { makeStyles } from "@material-ui/core/styles";

// this is how we will use the Text component
function App() {
  const style = {
    title: {
      fontSize: "80px",
      color: "red",
      "@media (max-width: 767px)": {
         color: "green"
      }
    },
    notGoodPractice: {
      fontSize: "80px"
    }
  };

  return (
    <div className="App">
      <Text class1={style.title}>Title should be with size 80px</Text>
      <Text class1={style.notGoodPractice}>Title should be with size 80px</Text>
    </div>
  );
}

// this will be a component in another folder, it will be used throw the in app so it should be as DYNAMIC as possible
function Text(props) {
  const useStyles = makeStyles(theme => ({
    default1: {
      fontSize: 18,
      color: "black"
    },
    priorityClass: props => props.class1
  }));

  const { default1, priorityClass } = useStyles(props);
  return <div className={`${default1} ${priorityClass}`}>{props.children}</div>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

查看实时沙盒https://codesandbox.io/s/zen-voice-mb60t

【讨论】:

  • 我在演示中清楚地看到了, .notGoodPractice: { fontSize: "80px !important" } 认为它是一个库,每个人都应该添加 !important 来设置组件的样式吗?!
  • 这就是我们已经实现的,但它似乎没有那么好扩展。假设我也需要添加阴影(仅在 1 种情况下),我们需要每天返回该组件。 + 您无法使用此解决方案进行 媒体查询
  • 您可以在该场景中将单独的类仅传递给该组件
  • 不管怎样,如果你按照正常的方式做,你会这样做
  • 不要将它们传递给 makeStyles,这将是可扩展的解决方案
猜你喜欢
  • 2016-06-10
  • 2017-02-15
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 2017-06-06
相关资源
最近更新 更多