和 Angular,Vue 不同,React 并没有如何在 React 中书写样式的官方方案,依靠的是社区众多的方案。社区中提供的方案有很多,例如 CSS Modules,styled-components,styles jsx 等等。

接下来会详细地说一下这几种方案,在说这几种方案之前,首先说一下 React 官方提供的构建工具 create-react-app 构建的项目中使用 css 的问题。

使用 create-react-app 创建的项目引入 css 文件的问题

使用 create-react-app 构建一个项目之后,会有 index.js,index.css,App.js 等文件,为了说明问题我又新建了一个 App1.js 文件,为了简便文件内容让我删除改动了一些。

index.css

.huisiyuan {
background: red
}

index.js

import App from './App';
import App1 from './App1';
import './index.css'; ReactDOM.render(
<React.StrictMode>
<App />
<App1 />
</React.StrictMode>,
document.getElementById('root')
);

App.js

import React, { Component } from 'react';
class App extends Component {
render() {
return <div className='huisiyuan'>组件App</div>
}
}
export default App;

App1.js

import React, { Component } from 'react';
class App1 extends Component {
render() {
return <div className='huisiyuan'>组件App1</div>
}
}
export default App1;

index.js 中引入的 index.css 在浏览器中是出现在 head 标签下的 style 标签下,因此任何在 index.js 中使用的组件都可以使用 index.css 中的样式。

例如想让组件 App 的背景颜色为红色,index.css 中正好是这样设置的,但是 App1 中的背景颜色也会跟着变成红色。

说明了 creat-react-app 创建项目后直接使用 import 引入 css 文件出现的问题,接下来讲一下社区中提供的各种方案。

CSS Modules

CSS Modules 的核心

CSS Modules更详细的介绍可以参考阮一峰老师 CSS Modules 用法教程

因为CSS的规则都是全局的,任何一个组件的样式规则,都对整个页面有效,这可能会导致大量的冲突。例如,如果我有两个css文件,它们的中的一些样式名是一样的,那么就会被覆盖,简单的解决办法就是将样式的命名变得复杂且不重复,但这样样式多了也很难避免重复,且命名变得复杂。

CSS Modules 就解决了这个问题,在一个组件中引入的类经过构建工具编译之后会变成独一无二的哈希字符串.

下面是一个 App 组件

import React, { Component } from 'react';
import xxx from 'index.css'; class App extends Component { render() {
return <div className={xxx.huisiyuan}>组件App</div>
} } export default App;

和上面引入 css 文件不同的是,这里将 index.css 文件输入到 xxx 对象,xxx.huisiyuan 代表一个 class。

.huisiyuan {
background: red;
}

构建工具会将 xxx.huisiyuan 编译成一个哈希字符串,同样 index.css 文件中的 .huisiyuan 也将被编译成同样的哈希字符串,这样这个类名就独一无二了。

这样这个类就有了局域的概念,其它组件不引入使用这个 index.css 文件就不会应用到这个类的样式,因为编译后的哈希字符串其它组件是不知道的。

一般情况下,

局部样式文件 全局样式文件
命名方式 xxx.module.css xxx.css
引入方式 import xxx from './xxx.mouule.css' import './xxx.css'
用法
huisiyuan
huisiyuan

styled-components

styled-components 见名知义就是一个带样式的组件。

React 的一个理念就是 all in JS,styled-components 将样式直接写入到组件中,得到的是一个样式的组件,在调用组件时是带着样式的。

Styled Component是react的一个第三方库,是CSS in JS 的优秀实践和代表,将CSS写在JS中,可以实现常规CSS所不好处理的逻辑复杂、函数方法、复用、避免干扰。

使用方法:

首先安装 style-components, npm install style-components --save.

下面的代码中 Div 就是一个带样式的组件(带样式的 Div)

import React, { Component } from 'react';
import styled from 'styled-components'; const Div = styled.div`
color: red;
`; class App extends Component { render() {
return (
<div>
<Div big>hello world</Div>
</div>
)
} } export default App;

右下图可以看出,styled-components 自动给 div 加了一个 class。

styled-components 还可以获取到组件的属性,并且在定义样式时进行一些逻辑操作。

const Div1 = styled.div`
color: red;
${(props)=> props.big&&`
font-size: 72px
`}
`; const Div2 = styled.div`
color: blue;
${(props)=> props.small&&`
font-size: 30px
`}
`; class App extends Component {
render() {
return (
<div>
<Div1 big>hello world</Div1>
<Div2 small>hello world</Div2>
</div>
)
}
}

当 Div1 组件中有 big 属性时会设置 font-size: 72px,结果如下图。

styled jsx

见名知义就是带样式的 JSX,一般有下面三种形式。

1) 行内样式

行内样式是一种最基本的写法,和在HTML中写的元素内联样式差不多,但是设置的样式是一个对象。

<div style={{color: red, background: blue}}>hello<div/>

为什么要用两个大括号?

因为在JSX中渲染的JS表达式,它们必须被放在一对大括号里,{style}可以视为一个JS对象。所以第一对大括号正是将JS表达式放入JSX解析,里面的那对大括号则创建了一个style对象实例,所以在这里style是作为一个对象传入组件 。

2)声明样式

声明样式其实是行内样式的一种改进写法,在render函数外部创建style对象,然后传递给组件,让css与标签分离 。

const style = {
color: red,
background: blue
} class App extends Components {
render() {
return (
<div style={style}>hello</div>
)
}
}

3)引入样式文件

其实这一种是 CSS Modules 中全局样式文件的应用,在这里再提一下,用法比较简单就是将样式文件通过 import 语句引入进来,问题就是页面上的所有组件都能应用这个文件中的样式。

App.css

.huisiyuan {
color: red;
background: blue;
}

App.js

import React, { Components } from 'react';
import './App.css';
import App1 from './App1'; class App extends Components {
render() {
return (
<App1 >
)
}
}

APP1.js

import React, { Components } from 'react'; 

class App1 extends Components {
render() {
return (
<div className='huisiyuan'>hello</div>
)
}
}

在 App.js 中引入了 App.css 但是在 App1.js 中·并没有引入,但是在 App1 组件内部依然可以使用 App.css 中的样式,App1 组件中hello 应用 App.css 中的样式,如下图所示。

总结:

上面总结的三种方法,推荐使用 CSS Modules 或者 styled-components,在平时做一些小 demo 的时候可以使用 styled jsx 的方法。

完,如有不恰当之处欢迎指正哦。

聊一聊 React 中的 CSS 样式方案的更多相关文章

  1. React中引用CSS样式的方法

    相对于html中引用css的三种方法,react中也有三种方法,一一相对: 1. 行内样式:直接在组件内部定义 <div style={{width:'20px',height:'30px'}} ...

  2. JQuery中操作Css样式的方法

    JQuery中操作Css样式的方法//1.获取和设置样式 $("#tow").attr("class")获取ID为tow的class属性 $("#tw ...

  3. html5 中的 css样式单 的 两种调用方式的区别

    在 html5 中 使用 css 样式单的方式 有4种: 1.链接外部样式文件:将样式文件 彻底与 html 文档分离,样式文件需要额外引入,这种情况下 一批样式 可以控制多份文档.对于好多文件都共有 ...

  4. HTML文档中应用css样式的方法总结

    在HTML文档中应用css样式大致有三种方法:1.link标签链接外部样式表:2.使用style元素包含样式表:3.使用style属性,即内联样式 一.link标签链接外部样式表 先看一条较为标准的l ...

  5. js中获取css样式属性值

    关于js中style,currentStyle和getComputedStyle几个注意的地方 (1)用js的style只能获取元素的内联样式,内部样式和外部样式使用style是获取不到的.针对css ...

  6. 【转发】JQuery中操作Css样式的方法

    JQuery中操作Css样式的方法 //1.获取和设置样式 $("#tow").attr("class")获取ID为tow的class属性 $("#t ...

  7. react中内联样式的z-index不起作用.

    <div style={{z-index: -100}} > hello,money. </div> 以上z-index样式如上写法是不起作用,原因是在react中内联样式的写 ...

  8. 在React中使用CSS Modules设置样式

    最近,一直在看React...那真的是一个一直在学的过程啊,从配置环境webpack,到基础知识jsx,babel,es6,没有一个不是之前没有接触的.其实,我内心是兴奋的啊,毕竟,活着就是要接触一些 ...

  9. React中使用CSS

    第一种: 在组件中直接使用style 不需要组件从外部引入css文件,直接在组件中书写. import React, { Component } from "react"; con ...

随机推荐

  1. C++中字符串的表示与转换

    转换总结 1.char*转string:可以直接赋值. 2.char[]转string:可以直接赋值. 3.char*转char[]:不能直接赋值,可以循环char*字符串逐个字符赋值,也可以使用st ...

  2. 用VS2013进行调试

    首先新建一个简单的C++程序 打开VS2013-文件-新建-项目-选择Win32 控制台程序 添加-新建项-选择C++源文件 编写如下代码 #include<iostream> using ...

  3. QA、EPG、PMO各自的职能划分及关系是什么?

    团队 职能 主要工作内容 EPG 负责过程持续改进工作 公司规范的建设和推广,并持续改进.收集过程改进需求,制定过程改进计划,获得高层的支持,并实施改进工作. PMO 负责公司内所有项目的审核.管理 ...

  4. NEWMING

    这里只是列举一些常用的文件操作命令. cd 跳转切换目录 # 格式:cd dirname 比如在打开用户主目录盘下的 myidoc 文件夹 cd ~/myidoc 跳转到当前目录的上一级 cd ../ ...

  5. 马云也看好!VR在2016年能否得到质变

    在2015年10月底有消息传出,国外虚拟现实公司Magic Lea的新一轮融资吸引到中国互联网巨鳄--阿里巴巴公司的关注.据透露,阿里巴巴极有可能为Magic Lea投资2亿美元.这虽然是阿里巴巴第一 ...

  6. Js对于数组去重提高效率一些心得

    最近在找工作,好几次面试都问过数组去重的问题.虽然问的都不一样,但是核心思想是没有变的. 第一种是比较常规的方法 思路: 构建一个新的数组存放结果 for循环中每次从原数组中取出一个元素,用这个元素循 ...

  7. C++扬帆远航——11(斐波那契数列)

    /* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:Feibo.cpp * 作者:常轩 * 微信公众号:Worldh ...

  8. ip修改成域名

    将ip修改成域名,这样的话可以使程序变得更加健壮,别人不能直接看见你的ip地址. 后来总结下分享给大家.首先找到hosts文件的位置,这个文件是系统dns默认查找的文件. windows 系统:C:\ ...

  9. date成字符串

    //获取当前时间 Date date=new Date(); System.out.println("当前date: "+date); //将时间转化成yyyy-MM-dd格式的字 ...

  10. python下载神通板砖有声版

    背景 前端时间在喜马拉雅上偶然听到牛大宝说的有声小说神通板砖,说的很是幽默,听的正起劲的时候开始收费了,于是我就在网上找了下看看有没有免费版,一搜果然有,但该网站上广告太多了,于是我就写了个小脚本可以 ...