欢迎来到3672js教程,我们关注js教程、js框架、js代码特效等。

React中编写CSS的姿势

3672Js.Com2019-08-04 12:05 来源:未知 阅读:2202 关注度5

React中编写CSS的姿势


在任何环境之下其实没有最佳,最有最适合,那么在React中编写CSS也是类似的。在React中有很多编写CSS的方式,在社区中讨论最多的应该是CSS In JS 和 CSS Modules。前段时间在《React中CSS Modules的使用》一文中探讨了在React中怎么使用CSS Modules来管理组件和项目的CSS。事实上,使用CSS Modules还是存有一定的缺陷。这篇文章将会和大家一起聊聊React中编写CSS的姿势,然后再会花一些篇幅来讨论CSS Modules编写CSS的最佳姿势。

React中编写CSS的系列痛点

其实我自己在React中编写CSS并不多,因为以前都是基于Vue的体系来做项目。现在切换到React技术栈,尝试着使用React来构建项目和组件库。到目前为止,我在项目React中使用过两种方式编写CSS:

  • 原生CSS结合处CSS处理器(Sass和PostCSS):该方式样式易于全局污染,多人协作易于发生冲突
  • 使用CSS Modules编写CSS,相比原生CSS是舒服多了,但引用组件库(独立库)就有点蛋疼,组件库样式覆盖令人头疼

这只是自己初步的感觉。但@Vjeux在分享CSS-in-JS时就抛出了React中编写CSS时令人头痛的一系列问题:

  • 全局污染:在CSS中,选择器的作用域概念并不太强,其机制虽然方便我们重写样式,但也带来痛楚,易于污染全局
  • 命名混乱:在多人协作(有的时候甚至是自己个人)在维护或开发一个项目的时候,容易造成样式冲突;而且命名混乱,难于维护。虽然BEM可以这种现象更好些,但还是难于避免命名的混乱,特别是在样式多变的情况之下
  • 依赖管理不彻底:组件应该是相互独立的,在引入一个组件时,应该只引入组件所需要的样式。但现在的做法是除了要引入JavaScript之外,还需要引入组件的CSS。不过组件自身无法彻底的管理相关的样式依赖。当然,到目前为止,Webpack的一些loader可以让这方面有所改善
  • 无法共享变量:复杂组件要使用JavaScript和CSS来共同处理样式,比如通过状态来动态更改样式风格。这样就需要通过JavaScript来处理CSS,就会造成有些变量在JavaScript和CSS中冗余。有可能CSS自定义属性会让这方面有所改变,但需相关验证

React中编写CSS常见的方式

在React社区中有关于如何在React中编写CSS的讨论也非常的热烈,而常见的方式是以下几种:

  • Inline CSS
  • CSS In JS
  • Styled Components
  • CSS Modules

不过每种方式都有自己的利弊,也各有争议。接下来我们先不好坏,分别来体验一下这几种方式写CSS的不同之处。

在开始之前,先使用Create React APP来构建React的项目,用来验证React项目中编写CSS的不同之处。

╰─➤  npx create-react-app react-styling
╰─➤  cd react-styling
╰─➤  npm run start

React在没有任何其他工具的情况之下,仅支持两种处理样式的方式:style道具(props)与<style>标签和CSS样式表。style道具使用JavaScript对象(CSS属性和值),并最终将其转换为元素的内联样式,如下所示:

// JSX
<p style={{backgroundColor: 'red'}}>Hello, {props.name}</p>

还可以这样写:

// App Components
// JSX
<p style={{ backgroundColor: props.color }}>Hello, {props.name}</p>

// index.js
import App from './App';
ReactDOM.render(<App name="大漠" color="#306"/>, document.getElementById('root'));

第一种是和我们平时在DOM中的元素上使用style属性设置行内样式是一样的;第二种是使用props的给style设置样式,编译出来也是行内样式。这两种方式输出来的样式都是行内样式,如果从选择器权重来说,它的权重是非常高的,在调用组件,要覆盖其样式就不容易了。

我们还可以在一个样式表文件中设置样式,比如在App.css文件中:

.App {
    text-align: center;
}

.App-logo {
    animation: App-logo-spin infinite 20s linear;
    height: 40vmin;
    pointer-events: none;
}

App组件中可以通过className来调用App.css中的类名:

// App.js
import './App.css';

function App(props) {
    return (
        <div className="App">
            <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p style={{ backgroundColor: props.color }}>Hello, {props.name}</p>
            </header>
        </div>
    );
}

编译出来之后如下图所示:

这是React中编写CSS最基本的方式。这两种基本方式和我们在普通的Web中编写CSS方式是一样的。众所周知,Web中编写CSS是较为痛苦的,因为类名的冲突,全局的污染等等。所以社区才会借助一些工具的方式来改变编写CSS。

Inline CSS

Inline CSS称为内联CSS,即在HTML标签元素中使用style属性(Attribute)来定义CSS属性,常被称为行内样式。如下面这样:

<p style="font-size: 20px; color:#4a54f1; text-align:center; padding-top:100px;">
    Hello World!!!
</p>

而在Web中,我们一直提倡的是结构和样式分离,所以一直不推荐行内样式这样的写法。而如今天在React框架体系中,又开始提Inline CSS,那么是不是有点倒退了的意思呢?该话题先不讨论,这里咱们只来聊聊Inline CSS在React中的使用,并且该使用是否适合我们的开发习惯。

在React开发中,我们一般使用JSX编写。JSX将被转换为React.createElement(...),所有的属性都将成为props对象的一部分。

在React中,内联样式不指定为字符串style属性接受带有驼峰格式的JavaScript对象。例如:

margin-top       ─➤ marginTop
border-radius    ─➤ borderRadius
font-weight      ─➤ fontWeight
background-color ─➤ backgroundColor

下面是React中定义内联CSS的基本步骤:

  • 将CSS属性名称用驼峰的格式编写,比如font-size要写成fontSize
  • 创建一个对象,将所有CSS属性作为key,CSS属性的值作为value
  • 将该对象分配给style属性

我们来尝试着将上面的HTML代码,看看在React中怎么来实现:

// App.js
import React from 'react';

function App() {
    const styleObj = {
        fontSize: '20px',
        color: '#4a54f1',
        textAlign: 'center',
        paddingTop: '100px'
    }
    return (
        <p style={ styleObj }>Hello World!!!</p>
    );
}

export default App;

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

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

你将看到的效果如下:

上面的写法和JSX中在style中引入需要的样式得到的结果是一样的

剩余80%内容付费后可查看 本部分为付费内容,支付后可查看 支付3.99元 已支付,使用阅读码 包月会员登录 购买包月会员推荐 * 请输入阅读码(忘记阅读码?)

本站文章为3672js教程网友分享投稿,版权归原作者,欢迎任何形式的转载,但请务必注明出处。同时文章内容如有侵犯了您的权益,请联系我们处理。
评论已被关闭
{dede:include filename="foot.htm"/}