React 样式添加的三种姿势:从行内到 CSS-in-JS 的踩坑实录

63 阅读1分钟

1. 行内样式:最熟悉的陌生人

function Button() {
  return (
    <button
      style={{
        backgroundColor: "#3b82f6",
        color: "#fff",
        padding: "8px 16px",
        border: "none",
        borderRadius: "4px",
        cursor: "pointer",
      }}
    >
      点我
    </button>
  );
}

心跳时刻:为什么 background-color 要写成 backgroundColor
答:因为 style 接收的是 JS 对象,CSS 属性必须转为驼峰命名。

踩坑
当需要伪类(hover)或媒体查询时,行内样式直接 GG。此时需要...


2. 普通 CSS 文件:最经典的方案

/* Button.module.css */
.btn {
  background-color: #3b82f6;
  color: #fff;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
}

.btn:hover {
  background-color: #2563eb;
  transform: translateY(-1px);
}
import styles from "./Button.module.css";

function Button() {
  return <button className={styles.btn}>点我</button>;
}

心跳时刻
.module.css 是 CSS Modules 的写法,React 脚手架会自动把类名哈希化,避免全局污染。
(如果你用 Vite,记得在 vite.config.js 里开启 css.modules


3. CSS-in-JS:当样式变成组件

这里用 styled-components 举例:

npm install styled-components
import styled from "styled-components";

const Button = styled.button`
  background-color: #3b82f6;
  color: #fff;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;

  &:hover {
    background-color: #2563eb;
    transform: translateY(-1px);
  }

  /* 动态 props */
  ${(props) =>
    props.$primary &&
    `
    background-color: #ec4899;
    &:hover {
      background-color: #db2777;
    }
  `}
`;

function App() {
  return (
    <>
      <Button>普通按钮</Button>
      <Button $primary>主要按钮</Button>
    </>
  );
}

心跳时刻
$primary$ 前缀是为了避免把 props 透传到 DOM 节点(React 会报警告)。


4. 实战对比:一个卡片组件的三种实现

方案代码量可维护性动态样式SSR 支持适合场景
行内样式快速原型、简单组件
CSS Modules常规业务、团队协作
styled-components极好复杂主题、设计系统

5. 我的选择法则

  1. MVP 阶段:行内样式 + 一个全局 index.css,最快上线。
  2. 团队协作:CSS Modules + clsx 处理条件类名。
  3. 设计系统:styled-components + styled-system 做主题令牌。

6. 加餐:TailwindCSS 的另一种哲学

<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Tailwind按钮
</button>

心跳时刻
Tailwind 的本质是「原子化 CSS 库」,不是 CSS-in-JS。
如果你讨厌写样式,但又想保持可控,可以试试它。


附录:常见报错速查表

错误信息原因解决
Warning: Received 'true' for non-boolean attribute 'primary'styled-components 的 props 没加 $ 前缀改成 $primary
Unknown property 'class'...写成了 class 而不是 className改!
Cannot find module './Button.module.css'没安装 CSS Modules 支持检查 webpack/vite 配置

下一篇预告:《从 JSX 的花括号到列表 key 的 5 个高频疑问》
点赞超过 50 我就熬夜写!