React中css的使用方式

152 阅读1分钟

前言

本篇主要总结一些react使用css的方式,如有不准确的地方欢迎指出,共同学习,相互进步!

一. 内联样式

  • 优点:可以动态获取当前state中的状态
  • 缺点: 代码混乱,某些样式无法编写(比如伪类/伪元素)
import React, { PureComponent } from 'react'

export class App extends PureComponent {
  constructor() {
    super()

    this.state = {
      titleSize: 30
    }
  }

  addTitleSize() {
    this.setState({ titleSize: this.state.titleSize + 2 })
  }

  render() {
    const { titleSize } = this.state

    return (
      <div>
        <button onClick={e => this.addTitleSize()}>增加titleSize</button>
        <h2 style={{color: "red", fontSize: `${titleSize}px`}}>我是标题</h2>
        <p style={{color: "blue", fontSize: "20px"}}>我是内容</p>
      </div>
    )
  }
}

export default App

二. css单文件引入

  • 优点: 解决了局部作用域的问题
  • 缺点:1. 引用的类名,不能使用连接符(.xxx-xxx),在JavaScript中是不识别的;2. 所有的className都必须使用{style.className} 的形式来编写;3.不方便动态来修改某些样式,依然需要使用内联样式的方式;
import React, { PureComponent } from 'react'
// import "./Home.css"
import homeStyle from "./Home.module.css"

export class Home extends PureComponent {
  render() {
    return (
      <div className={homeStyle.section}>
        <div className={homeStyle.title}>Home的标题</div>
      </div>
    )
  }
}

export default Home

三. CSS in JS(styled-components)

CSS-in-JS通过JavaScript来为CSS赋予一些能力,包括类似于CSS预处理器一样的样式嵌套、函数定义、逻辑复用、动态修改状态等。

  • 优点: 动态修改样式 CSS-in-JSReact编写CSS最为受欢迎的一种解决方案
npm i styled-components

styled component中,就是通过ES6中模板字符串语法的标签模板字符串来解的,最终生成我们想要的样式。

举例:


// ES6: 标签模板字符串
const name = "amy"
const age = 18

//1.模板字符串的基本使用
const str = `my name is ${name}, age is ${age}`
console.log(str)  //my name is amy, age is 18

//2.标签模板字符串的使用
function foo(...args) {
  console.log(args)
}

//foo("amy", 18, 1.88) //[ 'amy', 18, 1.88 ]
 foo`my name is ${name}, age is ${age}` //[ [ 'my name is ', ', age is ', '' ], 'amy', 18 ]

//variables,js
export const primaryColor = "#ff8822"
export const largeSize = "18px"
//style.js
import styled from "styled-components";
import {
  primaryColor,
  largeSize
} from "./style/variables"
"

//支持样式的继承
const HYButton = styled.button`
  border: 1px solid red;
  border-radius: 5px;
`

export const HYButtonWrapper = styled(HYButton)`
  background-color: #0f0;
  color: #fff;
`


export const HomeWrapper = styled.div`
  .top {
    .banner {
      color: red;
    }
  }

  .bottom {
  //styled设置主题
    .header {
      color: ${props => props.theme.color};
      font-size: ${props => props.theme.size};
    }

    .product-list {
      .item {
        color: blue;
      }
    }
     .content {
      font-size: ${largeSize}px;
      color: ${primaryColor};
    }
  }
`
import React, { PureComponent } from "react";
import { HomeWrapper, HYButtonWrapper } from "./style";
import { ThemeProvider } from "styled-components";// styled设置主题


export class Home extends PureComponent {
  constructor() {
    super();

    this.state = {
      size: 30,
      color: "yellow",
    };
  }
  render() {
    const { size } = this.state;

    return (
       <ThemeProvider theme={{ color: "purple", size: "50px" }}>
      <HomeWrapper>
        <div className="top">
          <div className="banner">BannerContent</div>
        </div>
        <div className="bottom">
          <h2 className="header">商品列表</h2>
          <ul className="product-list">
            <li className="item">商品列表1</li>
            <li className="item">商品列表2</li>
            <li className="item">商品列表3</li>
          </ul>
          <h2 className="title">我是标题</h2>
          <p className="content">我是内容</p>
          <button onClick={(e) => this.setState({ color: "skyblue" })}>
            修改颜色
          </button>
        </div>
        <HYButtonWrapper>哈哈哈</HYButtonWrapper>
      </HomeWrapper>
      </ThemeProvider>
    );
  }
}

export default Home;

由上方可知props可以被传递给styled组件:

  • 获取props需要通过${}传入一个插值函数,props会作为该函数的参数

  • 这种方式可以有效的解决动态样式的问题

同时还可以添加添加attrs属性:

// 可以通过attrs给标签模板字符串中提供的属性
export const SectionWrapper = styled.div.attrs(props => ({
  tColor: props.color || "blue"
}))`
  border: 1px solid red;

  .title {
    font-size: ${props => props.size}px;
    color: ${props => props.tColor};

    &:hover {
      background-color: purple;
    }
  }

`

四. classnames库(动态添加classnames的一个库)

npm i classnames
import React, { PureComponent } from 'react'
import classNames from 'classnames'

export class App extends PureComponent {
  constructor() {
    super()

    this.state = {
      isbbb: true,
      isccc: true
    }
  }

  render() {
    const { isbbb, isccc } = this.state

    const classList = ["aaa"]
    if (isbbb) classList.push("bbb")
    if (isccc) classList.push("ccc")
    const classname = classList.join(" ")

    return (
      <div>
        <h2 className={`aaa ${isbbb ? 'bbb': ''} ${isccc ? 'ccc': ''}`}>哈哈哈</h2>
        <h2 className={classname}>呵呵呵</h2>
        <h2 className={classNames("aaa", { bbb:isbbb, ccc:isccc })}>嘿嘿嘿</h2>
        <h2 className={classNames(["aaa", { bbb: isbbb, ccc: isccc }])}>嘻嘻嘻</h2>
      </div>
    )
  }
}

export default App