styled-components 笔记 🔨
约 876 字大约 3 分钟
2025-12-14
styled-components 是 React 生态中最成熟、最符合直觉的 CSS-in-JS 方案之一,它允许你直接在 TSX 中书写原生 CSS,同时自动完成样式隔离、命名和注入,非常适合真实业务开发
核心理念
styled-components 的核心思想是:样式即组件的一部分,组件和样式天然绑定,而不是通过全局 class 或文件名关联
- 样式只作用于当前组件
- 样式与组件生命周期一致
- 通过 JS 能力增强 CSS 表达力
安装与基础配置
npm install styled-components
npm install -D @types/styled-components如果你使用 Vite / CRA,默认即可工作;SSR(Next.js)需要额外配置
创建第一个样式组件
import styled from 'styled-components';
const Button = styled.button`
padding: 8px 16px;
border-radius: 6px;
border: none;
background: #1677ff;
color: #fff;
cursor: pointer;
`;- 使用
styled.xxx创建组件 - 模板字符串中书写的是原生 CSS
- 生成的组件可直接在 JSX 中使用
重点一句话:它已经是一个 React 组件了。
像普通 React 组件一样用,直接在 JSX 里用
function App() {
return (
<div>
<Button>点我</Button>
</div>
);
}- 不需要
className - 不需要 import css
- 样式已经自动注入到
<head>
默认支持所有 button 原生属性,都原样透传
<Button disabled onClick={() => alert('clicked')}>
提交
</Button>样式隔离与可读类名
styled-components 会自动生成类似下面的 class
Button-sc-kAzzGY-0
- 开发环境包含组件名,方便调试
- 样式天然隔离,无需担心冲突
- 生产环境会自动压缩
使用 Props 控制样式
这是 styled-components 在实际开发中使用频率最高的能力
const Button = styled.button<{ primary?: boolean }>`
background: ${p => (p.primary ? '#1677ff' : '#eee')};
color: ${p => (p.primary ? '#fff' : '#333')};
`;- 样式与组件状态强关联
- 支持完整 TypeScript 类型推导
- 比 class 切换更直观
条件样式与片段复用
import { css } from 'styled-components';
const dangerStyle = css`
background: #ff4d4f;
color: #fff;
`;
const Button = styled.button<{ danger?: boolean }>`
padding: 8px 16px;
${p => p.danger && dangerStyle}
`;css用于抽离可复用样式片段- 常用于主题、状态、尺寸系统
伪类、嵌套与媒体查询
styled-components 完整支持 CSS 能力
const Card = styled.div`
padding: 16px;
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.12);
}
@media (max-width: 768px) {
padding: 12px;
}
`;- 不需要额外配置
- 心智模型与写 CSS 文件完全一致
扩展已有组件样式
const PrimaryButton = styled(Button)`
background: #52c41a;
`;- 用于构建组件体系
- 不破坏原组件逻辑
全局样式
用于 reset、body 样式、主题背景等
import { createGlobalStyle } from 'styled-components';
const GlobalStyle = createGlobalStyle`
body {
margin: 0;
font-family: system-ui;
}
`;- 仅建议放基础样式
- 不要把业务样式写进全局
主题系统 ThemeProvider
import { ThemeProvider } from 'styled-components';
const theme = {
primary: '#1677ff',
radius: '6px'
};
const Button = styled.button`
background: ${p => p.theme.primary};
border-radius: ${p => p.theme.radius};
`;- 适合设计系统、暗黑模式
- theme 是隐式注入的 props
attrs 技巧
用于处理 class、type、默认属性
const Input = styled.input.attrs({ type: 'text' })`
padding: 8px;
`;- 常用于 form 组件
- 保持 JSX 干净
样式组织最佳实践
- 一个组件文件配一个 styled 定义
- 样式与组件放在同一目录
- 大组件可拆成
styles.ts - 避免在 styled 中写业务逻辑
性能与注意事项
- styled-components 有运行时开销,但对大多数业务可忽略
- 避免在 render 中创建 styled 组件
- 动态样式优先使用 props,而不是字符串拼接
SSR 与 Next.js 提示
- 需要收集样式并注入 HTML
- 官方文档提供完整示例
- 否则会出现样式闪烁