【问题标题】:react route how to import local scss file only apply to one js file?react route如何导入本地scss文件只适用于一个js文件?
【发布时间】:2020-03-16 00:37:57
【问题描述】:

在一个带有 React Router 的 React 应用程序中,对于每个路由组件,我希望有一个本地 scss 文件仅适用于该文件。

对于下面的例子,about.js 导入了 about.scss,我想要的是:about.scss 仅在 about.js 中覆盖 app.scss 中的全局样式。但是,它会覆盖应用中的所有内容

app.js - 导入的 app.scss 我更喜欢作为全局样式

import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import "./app.scss";  // global scss
import About from "./about";

export default function App() {
  return (
    <>
      <h1>question about scss in react route</h1>
      <Router>
        <div>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
          </ul>
          <hr />
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
        </div>
      </Router>
    </>
  );
}
function Home() {
  return (
    <div>
      <h3 className={"myMargin"}>home</h3>
    </div>
  );
}

app.scss(全局样式)

h3.myMargin {
  margin: 10px
}

about.js

import React from "react";
import "./about.scss";

export default function About() {
  return (
    <div>
      <h3 className={"myMargin"}>About</h3>
    </div>
  );
}

about.scss(我想成为本地风格,但是它适用于应用程序中的任何地方)

h3.myMargin {
  margin: 100px
}

对如何构建我的样式代码有什么建议吗?

【问题讨论】:

  • 您可以添加另一个特定于 about 组件的 className,然后相应地确定所有内容(例如.about h3.myMargin: { })。你可以使用css modules
  • ^^ 如果你使用 Create React App,他们的documentation 会提到如何使用 CSS 模块。

标签: reactjs sass react-router


【解决方案1】:

CSS 的美妙之处(和警告)在于其首字母缩写词的第一个 C ——代表 cascading——意味着有一系列(相当可预测的)规则要遵循。

在这种情况下,about.scss 稍后会被导入,无论如何都会覆盖来自应用程序的 h3。

1) 使用容器:

import React from "react";
import "./about.scss";

export default function About() {
  return (
    <div className='about-page'>
      <h3 className="myMargin">About</h3> // note: no need for {"myMargin"}
    </div>
  );
}

// about.scss
.about-page {
  h3.myMargin {
    margin: 10px
  }
}

2) 使用 CSS 模块:

另一种方法是使用 CSS 模块,如果您使用的是最新版本的 create-react-app,则默认启用:

import React from "react";
import styles from "./About.module.scss";

export default function About() {
  return (
    <div>
      <h3 className={styles.myMargin}>About</h3>
    </div>
  );
}

// About.module.scss
.myMargin {
  margin: 10px
}

这将生成一个唯一的类名,因此您处理的代码将如下所示:

<div>
  <h3 class='About_myMargin_mVxOd>About</h3>
</div>

随机散列(mVxOd 为例)将允许您的样式不会相互覆盖。

这两种方法各有优缺点,使用常规 CSS/SCSS 导入时最大的问题是您受制于 CSS 规则:如果您不小心创建了一个全局类.error,那么规则将级联到任何组件,并且很难跟踪。例如,导入 Bootstrap 会覆盖大量您不知道的 CSS 名称(直到您意识到您的 CSS 已关闭)。

另一个问题是,如果上述路由没有导入 CSS 文件,但后来遵循不同的路由路径确实导入了文件,那么您最终可能会得到不同的样式。这在我们身上发生过几次,因此必须格外小心,尤其是在较大的团队中。

CSS 模块有一些很大的缺点,第一个是你不能通过覆盖另一个 CSS 文件的 CSS 类来直接覆盖另一个 CSS 文件中的样式(因为上述哈希)。其次,您不能访问 SASS 允许的嵌套 CSS 选择器。

我个人在生产和个人项目中都使用过,两者都同样出色——小心使用时。

还有第三种流行的选项,称为样式化组件。这不是我个人的首选,我也没有太多使用它,但你可以在它的official page 上了解更多关于它的信息。它看起来像这样:

const Title = styled.h3`
  margin: 10px;
`

render() {
  return <Title>About</Title> // creates an h3 tag
}

最后一个,是 JS 中的 CSS,我也用得不够。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 2021-11-03
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多