1057 字
5 分钟
05.React中的样式
2025-03-28

内联样式#

内联样式是官方推荐的一种 CSS 样式写法:

  • Style 接受一个采用小驼峰命名属性的 JS 对象,而不是CSS字符串;

  • 可以引用 state 中的状态来设置相关的样式。

render() {
    const pStyle = {
        color: 'orange'
    }
    return (
        <div style={{ fontSize: '50px', color: 'red' }}>
            Hello World
        </div>
        <p style={pStyle}>
            Hello React
        </p>
    )
}

优点#

  1. 样式之间不会有冲突;

  2. 可以动态的获取当前 state 中的状态。

缺点#

  1. 写法上都需要驼峰标识;

  2. 某些样式没有提示;

  3. 大量的样式,使代码混乱;

  4. 某些样式无法编写(如伪元素)。

普通CSS#

  • 普通 CSS 我们通常会编写到一个单独的文件,之后再进行引入;

  • 这样的编写方式和普通的网页开发中编写方式是一致的;

    • 但我们希望组件是一个独立的模块,即使是样式也只在组件内部生效,不会互相影响;

    • 但普通的 CSS 都属于全局效果,样式之间会互相影响;

  • 普通 CSS 会出现样式之间互相层叠掉。

CSS modules#

CSS modules 并不是 React 特有的解决方案,而是所有使用了类似于 webpack 配置的环境下都可以使用的。

React 脚手架已经内置了 CSS modules 的配置。

CSS 代码:

.title {
    color: red;
}

在需要引入 CSS 的文件中进行如下处理:

import React from 'react'
import appStyle from './style.module.css'
...
    return (
        <h2 className={appStyle.title}>Hello World</h2>
    )

优点:#

  • 解决了局部作用域的问题,CSS 代码间不会相互影响。

缺点:#

  • 引用的类名不能使用连接符(.title-header),在JS中无法识别;

  • 所有 className 都必须使用 {style.className} 的形式来编写;

  • 不方便动态来修改某些样式,依然需要使用内联样式的方式。

CSS in JS#

CSS in JS 是一种模式,其中 CSS 由 JS 生成而不是在外部文件中定义。

此功能并不是 React 的一部分,而是由第三方库提供。React 对样式如何定义并没有明确的态度。

  • 在传统的前端开发中,我们通常会将结构(HTML)、样式(CSS)、逻辑(JavaScript)进行分离。

    • 但在 React 中,认为逻辑本身和 UI 是无法分离的,所以才有了 JSX;

    • 样式也是 UI 的一部分;

    • React 重要的观点之一便是“All in JS”。

styled-components#

目前(2023)styled-components 是社区最流行的 CSS in JS 库。

  • 安装 styled-components:
yarn add styled-components
  • 安装 vscode-styled-components 插件

  • 引入库并使用:

import React, { PureComponent } from 'react'
import styled from 'styled-components'

const AppWrapper = styled.div`
  font-size: 50px;
  color: red;
  .banner {     // CSS嵌套语法
    background-color: pink;
    span {
      color: white;

      &.active {     // 对<span className="active"></span>产生影响
        color: red;
      }
      &:hover {    // 意味span:hover {}
        color: aquamarine;
      }
      &::after {
        content: '!';
      }
    }
  }
`

export default class App extends PureComponent {

  render() {
    return (
        <AppWrapper>
          Hello World
          <div className='banner'>
            <span>Hello React&nbsp;&nbsp;&nbsp;</span>
            <span className='active'>Hello React&nbsp;&nbsp;&nbsp;</span>
            <span>Hello React&nbsp;&nbsp;&nbsp;</span>
          </div>
        </AppWrapper>
    )
  }
}
  • 分文件时的引入和导出问题:
// 需引入CSS的组件:
import {AppWrapper} from './style' // 解构赋值
// CSS文件:
import styled from 'styled-components'

export const AppWrapper = styled.div`
    ......
`

属性穿透和attrs的使用#

如果遇上 HTML 标签自带的属性,那么 styled-components 有两种解决方案:

  1. 方案一:
// CSS文件:
export const Input = styled.input`
    background-color: pink;
`
// 需求组件:
<Input type='password'/>    // 发生了属性穿透,正常显示
  • 方案二:
// CSS文件:
export const AttrsInput = styled.input.attrs({
    placeholder: 'Sytus',
    type: 'text'    // 参数是一个对象,会重新返回一个函数
})`    
    color: red;
`
// 需求组件:
<AttrsInput/>

其中方案二的能力更为强大:

const HYInput = styled.input.attrs({
  bcolor: 'red'
})`
  border-color: ${props => props.bcolor};
  color: ${props => props.color};
`    // porps 会收集 attrs 和 组件传进来的参数
    
export default class App extends PureComponent {
  constructor(props) {
      super(props)
      this.state = {
          color: 'pink'
      }
  }
  render() {
    return (
    <div>
        <HYInput type="password" color={this.state.color} />
    </div>
    )
  }
}

属性继承#

const HYButton = styled.button`
    padding: 10px 20px;
    color: red;
`
// 实例代码
/*const HYPrimaryButton = styled.button`
    padding: 10px 20px;
    color: white;
`*/

const HYPrimaryButton = styled(HYButton)`
    color: white;
`
   
export default class App extends PureComponent {
    render() {
    return (
    <div>
        <HYButton>这是普通按钮</HYButton>
        <HYPrimaryButton>这是主要按钮</HYPrimaryButton>
    </div>
    )
  }
}

主题#

父组件中引入主题:

import styled, {ThemeProvider} from 'styled-components'

父组件中 return 函数内:

return (
    <ThemeProvider theme={{themeColor: 'pink', fontSize: '30px'}}>
        <Home />
    </ThemeProvider>
)

Home 组件的 CSS 文件 中:

export const HomeStyle = styled.H2`
    color: ${props => props.themeColor};
    font-size: ${props => props.fontSize};
`
05.React中的样式
https://sytusramlethal.github.io/posts/05react中的样式/
作者
Sytus Ramlethal
发布于
2025-03-28
许可协议
CC BY-NC-SA 4.0