# styled-components 与 Emotion（CSS-in-JS）

URL: https://caijiao.org/react/chapter12/styled-components
Source: docs/react/chapter12/styled-components.md
Description: styled-components 和 Emotion 是两种流行的 CSS-in-JS 解决方案，它们允许开发者在 JavaScript 中编写和管理组件的样式，提升了样式的可维护性与灵活性。

`styled-components` 和 `Emotion` 是两种广泛使用的 CSS-in-JS 解决方案，它们允许开发者将 CSS 样式与 JavaScript 逻辑紧密结合，提升了组件样式的可维护性与灵活性。这些工具在 React 和其他现代 JavaScript 框架中被广泛应用。

## 1. 什么是 CSS-in-JS？

CSS-in-JS 是一种将 CSS 样式写入 JavaScript 文件中的方法。与传统的分离 CSS 的做法不同，CSS-in-JS 使得样式与组件紧密耦合，能够根据组件的状态动态生成样式。CSS-in-JS 提供了一种更具模块化和动态化的方式来管理应用中的样式。

## 2. styled-components 介绍

`styled-components` 是一个流行的 CSS-in-JS 库，它允许你在 JavaScript 中直接编写样式，并且将样式绑定到组件上。每个组件的样式都是局部作用域的，且不受全局样式影响。

### 基本用法

首先需要安装 `styled-components`：

```bash
npm install styled-components
````

然后在组件中使用：

```jsx
import styled from 'styled-components';

const Button = styled.button`
  background-color: blue;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;

  &:hover {
    background-color: darkblue;
  }
`;

function App() {
  return ;
}
```

在上面的例子中，我们使用 `styled.button` 创建了一个具有特定样式的按钮组件。

## 3. Emotion 介绍

`Emotion` 是另一个强大的 CSS-in-JS 库，提供了与 `styled-components` 类似的功能，但它在性能优化和 API 设计上有所不同。`Emotion` 提供了两个主要的 API：`styled` 和 `css`，这使得开发者可以选择最适合的方式来编写样式。

### 基本用法

首先需要安装 `Emotion`：

```bash
npm install @emotion/react @emotion/styled
```

然后在组件中使用：

```jsx
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';

const buttonStyle = css`
  background-color: blue;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;

  &:hover {
    background-color: darkblue;
  }
`;

function App() {
  return <button css={buttonStyle}>Click Me</button>;
}
```

这里我们使用了 `css` 来定义样式，并将其直接传递给组件。

## 4. styled-components 与 Emotion 的对比

### 样式书写方式

* **styled-components**：通过 `styled` API 创建样式化组件，直接将样式写入组件的定义中。
* **Emotion**：提供了 `styled` API 和 `css` API，可以选择写入样式的方式。`styled` 与 `styled-components` 类似，而 `css` API 使得样式的定义更加灵活和可复用。

### 性能

`styled-components` 和 `Emotion` 都非常注重性能。`Emotion` 在性能优化方面有所领先，尤其是在大规模应用中，`Emotion` 可以提供更高效的样式注入和动态样式计算。`styled-components` 也经过优化，但在极端性能需求下，`Emotion` 可能更具优势。

### 兼容性

`styled-components` 和 `Emotion` 都支持 SSR（服务器端渲染）。它们通过生成样式表并在服务端渲染时注入样式，确保客户端和服务端的样式一致。

### 可用性和生态系统

* **styled-components**：生态系统成熟，社区活跃。大量的教程、示例以及其他相关工具（如 `babel-plugin-styled-components`）。
* **Emotion**：虽然 `Emotion` 比较年轻，但它的灵活性和性能使它逐渐成为开发者的首选。它也有一个强大的社区，并且兼容 `styled-components` 的 API。

## 5. 总结

`styled-components` 和 `Emotion` 都是强大的 CSS-in-JS 解决方案，它们各自具有不同的优势和特性。`styled-components` 提供了一个清晰和一致的 API，适合大多数 React 开发者。而 `Emotion` 则提供了更多的灵活性和性能优化，适用于需要极致性能的场景。

无论选择哪一个工具，CSS-in-JS 都能有效地提升样式管理的可维护性和模块化，减少全局样式冲突的问题，提升开发效率。
