【问题标题】:How to load different .css files on different components of a react application?如何在反应应用程序的不同组件上加载不同的 .css 文件?
【发布时间】:2020-05-06 03:16:29
【问题描述】:

我有两个 .jsx 文件代表它们各自的组件。

第一个是,Blog.jsx

import React from "react";
import '../assets/css/blog.css';

export const Blog = () => (
    <div>
        <h1>Hello Blog</h1>
    </div>
)

及其各自的 CSS 文件 blog.css

div { background: #ff481f; }

第二个是Landing.jsx

import React from "react";
import '../assets/css/landing.css'

export const Landing = () => (
    <div>
        <h1>Hello Landing</h1>
    </div>
)

及其各自的 CSS 文件 landing.css

div { background: #86ff2b; }

我在 App.js 文件中添加了路由并调用了这两个组件的实例,该文件是 React 应用程序的默认文件。运行应用程序后,当导航到组件时,我遇到了两个组件的背景颜色相同的问题(它仅加载 landing.css 并且永远不会更改)。

如何解决每个组件仅使用其各自的 .css 文件并加载它的问题?

【问题讨论】:

  • React 不是基于 MVC,所以你必须分配不同的类,否则最新的样式将覆盖以前的样式
  • @BILAL 你的意思是使用类组件而不是函数组件吗?
  • 不,您使用哪种类型的组件都没有关系,每个组件的样式都不会独立。如果您需要为组件制作独特的样式,只需使用 id 即可

标签: css reactjs


【解决方案1】:

不要使用 HTML 标签定义你的 CSS,因为它会影响你的整个应用程序。

使用 className、id 或内联样式。

like-App.css

  .myApp{ color: red;}
  #myApp2{ color: blue;}

App.js

import './App.css'

<div className="myApp">color changed by className</div>
<div id="myApp2">color changed by id</div>
<div style={{color:'red'}}>color changed by inline object styling</div> // inline styling

【讨论】:

  • 请不要将 id 用作 css 选择器
  • 请不要同时使用像 style={{color:'red'}} 这样的内联样式
  • @SaveliTomac 你能描述一下两者吗?
  • 第一: ID 具有高优先级(这是主要原因)dev.to/clairecodes/reasons-not-to-use-ids-in-css-4ni4 第二: 当你写 style={{color:'red' }} 你每次调用渲染时都会创建 new 对象,这意味着你的元素需要新的道具并且即使你的样式没有改变也会重新渲染
  • @SaveliTomac 我是否解释了我的解决方案中的特异性?...无论你在说什么,我都非常清楚。这是 reactjs 定义的语法。
【解决方案2】:

默认情况下webpack 和其他构建工具会将所有 CSS 文件编译为一个,即使 css 是在单独的 JSX 文件中导入的。因此,您不能使用不同的 CSS 文件并期望您不会影响页面的其他部分。

你有一些选择:

  1. 使用 BEM 来命名类名。
  2. 使用 cssModules。在这种情况下,元素将拥有自己的 css 类名,并且样式不会影响任何其他元素,除非您使用 :global 选择器。

【讨论】:

  • React 不编译任何东西,react 是将状态转换为视图的概念,css 文件是 webpack 或其他构建工具的烦恼。 Sass 与 BEM 无关,你可以在没有 SCSS 的情况下使用 BEM。当你说:所有页面都有自己的 CSS 样式你错了,css 模块解决了另一个问题。无论如何,您的答案都不是 OP 问题的答案。
  • 如我所说。 webpack 完全编译所有 CSS。没有反应。
  • 和 cssModule 解决了这个问题,因为正如我所说,所有页面都会有自己的 CSS 样式。如果您基于 cssModule 编写一些 CSS,您将看到样式不会影响任何其他页面。因为感谢babel ,它为元素生成随机名称并将它们用于样式。
  • 在你的编辑之后,答案变得更好了 :) 但是 css 模块对页面一无所知,css 模块解决了关于样式封装的问题 不在 页面中,css 模块适用于css 选择器,所以你应该了解基础知识
  • 我再次编辑答案。我想我们谈论一个共同点。使用 cssModule 我们可以防止 css 影响其他元素和页面(感谢使用 babel 和 cssModule 生成的随机 css 选择器)
【解决方案3】:

使用 html 标签作为 css 选择器是一种不好的做法(因为存在您描述的行为)。

您应该只使用 css 类或内联样式(使用 id 是另一种不好的做法,id 具有高优先级)。

div {
  width: 20px;
  height: 20px;
}

#id {
  background: red;
}

.class {
  background: green;
}
&lt;div id="id" class="class"&gt;&lt;/div&gt;

如果使用 css 类会出现同样的问题(当您有两个相似的类时)。这种情况是使用 css 模块 (构建规则集) 决定的,或者您可以使用 css-in-js (外部库),这有其优点和缺点。你也可以使用BEM(方法),如果你的应用程序不大,你可以避免这个麻烦。

css 模块 会将随机哈希添加到您的类中,而.my-awesome-class-name 您将获得.my-awesome-class-name-dew3sadf32s

因此,如果您在第一个文件中有两个类 .class 和第二个文件中的 .class,最后您将获得两个类 .class-dew23s2.class-dg22sf,您的样式将按预期解析。

css-in-js 是一种类似的方式,只是您应该使用 javascript 编写样式并获得一些好处,例如仅包含当前需要的样式 (您正在寻找的现在) 和其他几个。

您可以使用纯 css / scss / postcss / 等进行编码,但许多公司已经在 css 模块和 css-in-js 之间进行选择。

BEM 只是类名的命名约定。

最后 - 如果你使用 react 使用内联样式,你应该记住:

{} 是对象的构造函数,{} 在每次调用时都返回 new 对象,这意味着如果您编写如下内容:

class MyAwesomeComponent extends Component {
  render() {
    return <div style={{color: "red"}}></div>;
  }
}

class MyAwesomeComponent extends Component {
  render() {
    const divStyles = {color: "red"};

    return <div style={divStyles}></div>;
  }
}

div 将在每次您的render 调用时重新渲染,因为div 采用了新道具。

相反,你应该在你的类之外定义你的样式(例如):

const divStyles = {color: "red"};

class MyAwesomeComponent extends Component {
  render() {
    return <div style={divStyles}></div>;
  }
}

【讨论】:

  • 内联样式不一定是坏的,但不是一个好方法。因为将创建一个新对象,并且浏览器需要在每次重新渲染时重新计算样式。 link
  • @sepehr 我并不是说内联样式不好。我尝试警告使用内联样式:)
【解决方案4】:

如果您希望改进您​​的 css 导入/加载,这不是最佳解决方案。

但是,如果您不想深入研究 css,快速解决问题并继续使用 HTML 标签,这可能是最好的解决方案。

您可以为每个组件添加一个 div,为该 div 定义一个 Id 并包装该组件。之后在组件的 css 文件中,您将定义以 #id 开头的所有样式,因此所有 css 类或 HTML 标记将只影响相应的组件。

//App render in root
ReactDOM.render(
  <App />,
  document.getElementById('root')
);

//App
function App(props){
  return [
    <Blog />, <OtherComponent />
    ]
}
//Blog component
function Blog(props){
  return <div id="blog">
    <h1>I am Blog</h1>
    </div>
}

//Other component
function OtherComponent(props){
  return <div id="otherComponent">
    <h1>Im am other component</h1>
    </div>
}
/* blog.css*/
#blog h1{
color:yellow;
}

/* otherComponent.css*/
#otherComponent h1{
color:green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


<div id="root"></div>

【讨论】:

    猜你喜欢
    • 2017-11-03
    • 2020-12-30
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 2016-12-08
    • 2018-02-05
    相关资源
    最近更新 更多