更改 React 组件的 CSS 会影响所有其他页面
Changing the CSS for a React component has effect on all other pages
我有一个包含以下文件的 React 组件:
- src/components/HomePage/index.js
- src/components/HomePage/style.scss
组件很简单:
import React from 'react';
import './style.scss';
const HomePage = () => {
return (
<div className="homepage">
<h1>Landing page</h1>
</div>
);
};
export default HomePage;
在 style.scss
中,我将样式应用于所有 <h1>
标签:
h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
它按预期工作。但是,我现在看到 styles.scss
中的 h1 样式正在应用于我网站上的每个 h1,即使在不使用此组件的页面上也是如此。
我正在使用 Gatsby,但它本质上是一个 React 应用程序。我的理解是 React 的代码拆分功能会解决这个问题,来自 style.scss
的代码只会包含在使用我的组件的任何页面的包中。
我问的是为什么。我有两个简单的修复方法:
- 将
style.scss
中的所有内容包装在 .homepage
包装器中
- 使用 CSS 个模块并将文件重命名为
style.module.scss
。当我看到人们这样做时,他们总是从 './style.module.scss' 导入样式 - 有没有办法拥有 CSS 模块而不将其分配给这样的对象?
更新:在花了很多时间使用 React 之后回到这个问题,我认为 React 样式市场存在差距。 CSS 模块在我看来在语法上很糟糕,必须手动将所有内容包装在 .home
标记中以对其进行本地化是我不想做的手动工作。有人真的应该创建一个自动执行此操作的 React 插件,这样每当我有一个名为 Home.js
的文件并导入 Home.css
时,所有 CSS 都会自动限制为 Home.js
而无需我必须做一些特别的事情。
如果您想本地化 CSS 规则,则必须切换到 modular stylesheets(对 sass 样式表同样适用)。
在您当前的结构中,组件导入非模块化样式表并且不使用唯一标识符本地化更改。因此,添加的规则存在于全球范围内,没有唯一的标识符可以将它们本地化,以便只有选定的组件才能理解它们。这意味着它们能够轻松覆盖先前建立的同名规则(导入顺序在这里很重要,因为它将决定捆绑器如何附加输出样式表)。
因此,不要在 ./style.scss
文件中保存与组件相关的规则,而是将其重命名为 ./index.module.scss
,然后您将在组件中使用它,如下所示:
import React from 'react';
import styles from './index.module.scss';
const HomePage = () => {
return (
<div className={style.homepage}>
<h1 className={style.heading}>Landing page</h1>
</div>
);
};
export default HomePage;
您的样式表如下所示:
.heading {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
免责声明:
我已经将样式约定从通过标签选择元素更改为通过 class 选择它们,因为通过标签定位元素被广泛认为是一种不好的做法 [ref],但是如果您想要要维护它,则必须为此类规则提供父范围(它已经存在,因为父 <div/>
元素已分配 class。
在这种情况下,实现看起来像:
import React from 'react';
import styles from './index.module.scss';
const HomePage = () => {
return (
<div className={style.homepage}>
<h1>Landing page</h1>
</div>
);
};
export default HomePage;
和风格:
.homepage {
h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
}
您可以选择下面提到的最简单的方法。
import React from 'react';
import './style.scss';
const HomePage = () => {
return (
<div className = "home">
<div className="homepage">
<h1>Landing page</h1>
</div>
</div>
);
};
export default HomePage;
您可以将整个 html 包裹在一个 div 特定组件名称
中
CSS:
.home h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
这是最简单的方法。然而这是我个人的解决方案,因为我在刚开始接触 React 时也遇到了同样的问题。
我有一个包含以下文件的 React 组件:
- src/components/HomePage/index.js
- src/components/HomePage/style.scss
组件很简单:
import React from 'react';
import './style.scss';
const HomePage = () => {
return (
<div className="homepage">
<h1>Landing page</h1>
</div>
);
};
export default HomePage;
在 style.scss
中,我将样式应用于所有 <h1>
标签:
h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
它按预期工作。但是,我现在看到 styles.scss
中的 h1 样式正在应用于我网站上的每个 h1,即使在不使用此组件的页面上也是如此。
我正在使用 Gatsby,但它本质上是一个 React 应用程序。我的理解是 React 的代码拆分功能会解决这个问题,来自 style.scss
的代码只会包含在使用我的组件的任何页面的包中。
我问的是为什么。我有两个简单的修复方法:
- 将
style.scss
中的所有内容包装在.homepage
包装器中 - 使用 CSS 个模块并将文件重命名为
style.module.scss
。当我看到人们这样做时,他们总是从 './style.module.scss' 导入样式 - 有没有办法拥有 CSS 模块而不将其分配给这样的对象?
更新:在花了很多时间使用 React 之后回到这个问题,我认为 React 样式市场存在差距。 CSS 模块在我看来在语法上很糟糕,必须手动将所有内容包装在 .home
标记中以对其进行本地化是我不想做的手动工作。有人真的应该创建一个自动执行此操作的 React 插件,这样每当我有一个名为 Home.js
的文件并导入 Home.css
时,所有 CSS 都会自动限制为 Home.js
而无需我必须做一些特别的事情。
如果您想本地化 CSS 规则,则必须切换到 modular stylesheets(对 sass 样式表同样适用)。
在您当前的结构中,组件导入非模块化样式表并且不使用唯一标识符本地化更改。因此,添加的规则存在于全球范围内,没有唯一的标识符可以将它们本地化,以便只有选定的组件才能理解它们。这意味着它们能够轻松覆盖先前建立的同名规则(导入顺序在这里很重要,因为它将决定捆绑器如何附加输出样式表)。
因此,不要在 ./style.scss
文件中保存与组件相关的规则,而是将其重命名为 ./index.module.scss
,然后您将在组件中使用它,如下所示:
import React from 'react';
import styles from './index.module.scss';
const HomePage = () => {
return (
<div className={style.homepage}>
<h1 className={style.heading}>Landing page</h1>
</div>
);
};
export default HomePage;
您的样式表如下所示:
.heading {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
免责声明:
我已经将样式约定从通过标签选择元素更改为通过 class 选择它们,因为通过标签定位元素被广泛认为是一种不好的做法 [ref],但是如果您想要要维护它,则必须为此类规则提供父范围(它已经存在,因为父 <div/>
元素已分配 class。
在这种情况下,实现看起来像:
import React from 'react';
import styles from './index.module.scss';
const HomePage = () => {
return (
<div className={style.homepage}>
<h1>Landing page</h1>
</div>
);
};
export default HomePage;
和风格:
.homepage {
h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
}
您可以选择下面提到的最简单的方法。
import React from 'react';
import './style.scss';
const HomePage = () => {
return (
<div className = "home">
<div className="homepage">
<h1>Landing page</h1>
</div>
</div>
);
};
export default HomePage;
您可以将整个 html 包裹在一个 div 特定组件名称
中CSS:
.home h1 {
color: #f3f3f3;
font-family: "Cambria";
font-weight: normal;
font-size: 2rem;
}
这是最简单的方法。然而这是我个人的解决方案,因为我在刚开始接触 React 时也遇到了同样的问题。