# 使用 Context 实现跨层通信

URL: https://caijiao.org/react/chapter7/context
Source: docs/react/chapter7/context.md
Description: Context 是 React 提供的一种机制，用于在组件树中共享数据。使用 Context 可以避免通过多层嵌套的 'props' 传递数据，从而实现跨层组件的通信。它特别适用于主题设置、认证信息等全局数据的传递。

## 什么是 Context

Context 是 React 提供的一种机制，用于在组件树中共享数据。通过 Context，您可以在组件树中任何层级的组件之间共享状态，而不需要通过逐层传递 `props`。这使得跨越多个层级的组件通信变得更加简洁和高效。

## 创建和使用 Context

在使用 Context 时，首先需要创建一个 Context 对象，然后使用 `Provider` 来提供值，最后在需要共享数据的组件中使用 `Consumer` 或 `useContext` 来消费数据。

### 步骤 1：创建 Context

首先，我们需要使用 `React.createContext` 创建一个 Context 对象。

```jsx
import React, { createContext, useState } from 'react';

// 创建 Context 对象
const MyContext = createContext();

export default MyContext;
````

### 步骤 2：使用 Provider 提供数据

`Provider` 组件将一个值传递给组件树中的所有子组件。`Provider` 通常位于组件树的顶部，并包裹需要共享数据的部分。

```jsx
function Parent() {
  const [theme, setTheme] = useState('light');

  return (
    
  );
}
```

在上面的代码中，`Parent` 组件使用 `MyContext.Provider` 来传递当前主题信息 `theme` 和修改主题的函数 `setTheme`。

### 步骤 3：使用 `useContext` 消费数据

在需要使用共享数据的组件中，我们可以使用 `useContext` 钩子来访问通过 `Provider` 提供的值。

```jsx
import React, { useContext } from 'react';
import MyContext from './MyContext';

function Child() {
  const { theme, setTheme } = useContext(MyContext);

  return (
    <div>
      <p>当前主题: {theme}</p>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        切换主题
      </button>
    </div>
  );
}
```

在这个例子中，`Child` 组件通过 `useContext(MyContext)` 获取父组件 `Parent` 传递的 `theme` 和 `setTheme`。`Child` 可以使用这些数据并修改它们。

### 步骤 4：实现跨层通信

通过 Context，您可以将数据传递到组件树中的任何层级，而无需通过中间的组件传递 `props`。这使得在层级较深的组件之间共享数据变得更加方便和清晰。

### 总结

Context 是 React 提供的一种强大的机制，可以帮助我们在组件树中共享数据，而不需要逐层传递 `props`。它特别适用于处理全局数据，比如当前用户信息、主题设置等。通过 `Provider` 提供数据，使用 `useContext` 钩子或 `Consumer` 来消费数据，可以方便地实现跨层组件间的通信。
