React中书写css代码

React本身就是一个支持组件化的框架,但是React并没有对css处理好组件化。相较于VueVue这个一块就处理的很好,css放置在style标签中,而且可以设置scope作用域,防止样式覆盖,也可以设置css预处理器。

在组件化开发中我们需要书写局部的css,全局的css,动态的css(根据状态来设置css)。

React中书写css就没有那么的方便,下面介绍一些在Reactcss的书写方式。

内联样式

官方推荐的一种写法。

export default class componentName extends Component {
  render() {
    return (
      <div>
        <h2 style={{ color: "red", fontSize: "20px" }}>你好</h2>
        <h2 className='title'>世界</h2>
      </div>
    );
  }
}

css中短横线链接的属性需要转为小驼峰的形式来书写,以对象的形式书写css样式,同时可以引入state中的属性来动态引入属性。

当然缺点很明显,如果需要书写大量的代码,那这种方式一定不方便,没有代码提示等。另外一些样式也不能书写,伪元素等选择器是不能书写的。

普通的css引入

我们将css单独写在一个文件中,在引入到文件中。

import React, { Component } from "react";

import './index.css'

export default class componentName extends Component {
  render() {
    return (
      <div>
        <h2 style={{ color: "red", fontSize: "20px" }}>你好</h2>
        <h2 className='title'>世界</h2>
      </div>
    );
  }
}

但这样引入的css没有组件之间的作用域,是作用在全局的,属于全局css,会相互影响。所以适合写一些基本的全局样式。

css module 写法

该方法不是React自带的方法,只要在类似webpack配置打包环境下都可以使用。如果在其他项目中使用我们需要自己配置,配置webpack.config.js中的属性modules:true等。

React脚手架已经配置了css modules的配置。我们书写的.css/.less/.scss都需要修改为.module.css/.module.less/.module.scss

引入方式,需要一个变量来接受,className需要以{style.className}形式来书写

import React, { Component } from "react";

import style from  './index.module.css'

export default class componentName extends Component {
  render() {
    return (
      <div>
        <h2 style={{ color: "red", fontSize: "20px" }}>你好</h2>
        <h2 className={style.title}>世界</h2>
      </div>
    );
  }
}

这样就避免了作用域问题,渲染出来的className如下:
image-20211002221635289

当然缺陷也有,比如引入的类名不能是短横线连接,不方便修改属性。但这方法也是不错的css书写方式。

CSS in JS

通过js来增强Reactcss书写的一种方式。当然我们学些这个方式前先了解下ES6的一种语法,ES6标签模板字符串

我们使用该方法需要引入第三方库,这里推荐以下几个库:

  • styled-components
  • emotion
  • glamorous

我们以styled-components这个库来演示,这个库在社区中是很流行的。
安装方式:

//npm方式
npm install styled-components -S
//yarn方式
yarn add styled-components

该库本质上是调用函数来创建一个组件,组件会添加不会重复的class

该方式支持css预处理器的嵌套写法,支持css的各类写法。

基本用法:

import styled from "styled-components";
//创建一个组件
const TitleWrapper = styled.div`
  color: yellow;
  .title {
    background-color: tomato;
    &::after {
      content: "---aaa";
    }
  }
`;

这个函数中根元素为div,其中的样式只作用于该组件中

export default class CssInJS extends Component {
  state = {color:'pink'}
  render() {
    return (
      <div>
        <TitleWrapper>
          我是谁
          <h3 className="title">hahah</h3>
        </TitleWrapper>
      </div>
    );
  }
}

渲染结果:

image-20211002223406291

image-20211002223433566

props,attr属性

props可以穿透,直接作用在元素上

const InputWrapper = styled.input`
  background-color: red;
`;

export default class CssInJS extends Component {
  state = {color:'pink'}
  render() {
    return (
      <div>
        {/* 属性是可以穿透的,直接应用到标签上 */}
        <InputWrapper type="password"></InputWrapper>
      </div>
    );
  }
}

渲染结果:
image-20211002223726410

image-20211002223737638

另外获取props需要通过${}形式获取,其中定义一个函数,props会作为函数的参数。

const InputWrapper = styled.input`
  background-color: red;
  padding: ${(props) => props.padding};
`;
export default class CssInJS extends Component {
  state = { color: "pink" };
  render() {
    return (
      <div>
        <InputWrapper type="text" padding="20px"></InputWrapper>
      </div>
    );
  }
}

image-20211002224337778

image-20211002224407326

attr属性,为元素设置一些默认属性

const Input2Wrapper = styled.input.attrs({
  placeholder: "zhangsan",
  bColor: "red",//这种不存在的属性不能添加
  'data-day':111
})`
  background-color: #f2f2f2;
  color: ${(props) => props.color};
`;
export default class CssInJS extends Component {
  state = { color: "pink" };
  render() {
    return (
      <div>
        <Input2Wrapper color={this.state.color} />
      </div>
    );
  }
}

渲染效果:
image-20211002224915116

image-20211002224934768

高级特性

支持样式继承

我们可以将另一个组件传入函数中来实现样式的继承

const SuperButton = styled.button`
  padding: 8px 30px;
  border-radius: 5px;
`;

const MyButton = styled(SuperButton)`
  background-color: red;
  color: #bfa;
`;
export default class CssInJS extends Component {
  render() {
    return (
      <div>
        <MyButton>按钮</MyButton>
      </div>
    );
  }
}

渲染效果:

image-20211002230629918

image-20211002230653988

主题设置

import CIJ from "./cssInJS";
import { ThemeProvider } from "styled-components";
function App() {
  return (
    <div className="App">
      你好
      <ThemeProvider theme={{color:'#bcf', fontSize:'30px'}}>
        <CIJ></CIJ>
      </ThemeProvider>
    </div>
  );
}

export default App;

后代元素中获取theme中的属性

const TitleWrapper = styled.div`
  color: ${(props) => props.theme.color};
  font-size: ${(props) => props.theme.fontSize};
  .title {
    background-color: tomato;
    &::after {
      content: "---aaa";
    }
  }
`;

动态添加className

在项目中我们需要为组件动态的添加一些css类名,这在react中只能自己实现。

React没有为我们提供像Vue中的一些模板语法(比如一些指令v-bind等),我们可以借助一个第三方库classnames来简化我们的工作量。

//npm
npm install classnames -S
//yarn
yarn add classnames
import React, { Component } from 'react'

import classNames from 'classnames';

export default class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      isActive:true,
      info:'info'
    }
  }
  render() {
    return (
      <div>
        <h2 className={'title ' + (this.state.isActive?'active':'')}>你好</h2>
        <h2 className={classNames('foo', 'active')}>世界</h2>
        <h2 className={classNames({'title':this.state.isActive}, 'foo')}>000</h2>
        <h2 className={classNames({'title':this.state.isActive}, 'foo')}>111</h2>
        <h2 className={classNames({'title':this.state.isActive}, 'foo', this.state.info)}>222</h2>
      </div>
    )
  }
}

渲染结果:

image-20211002232559067

Last modification:March 7, 2022
如果觉得我的文章对你有用,请随意赞赏