React Context基本用法

192 阅读2分钟

Context

简介与前言

Context 提供了一种在组件之间共享此类的方式,不必显式通过组件树的逐层传递 props.

简单的理解

就是当我们想把最外层的属性传递给最内层的组件时,不需要一层层向子组件进行传递。

简单的逻辑

最外层组件创建一个 Context 对象。

最外层的组件用 Provider 包裹传递数据。

需要取值时通过 Consumer 取值。

在代码演示下有 API 讲解。

最简代码演示

./theme.ts

import { createContext } from 'react';

export const ThemeContext = createContext({} as any); // 这里可以在 `{}` 定义默认值

index.tsx(页面)

import React, { useState } from 'react';

import { ThemeContext } from './theme';
import BigComp from './BigComp'; // 外层的组件,下文有代码

export default () => {
  const [themeValue, setThemeValue] = useState('light');
  return (
    <ThemeContext.Provider  // 设置向下传递的参数
      value={{
        theme: themeValue,
        changeTheme: () => {
          setThemeValue('dark');
        },
      }}
    >
      <BigComp />
    </ThemeContext.Provider>
  );
};

BigComp.tsx // 外层组件

import React from 'react';
import SmallComp from './SmallComp';  // 内层的组件,下文有代码

export default () => (
  <div>
    this is a BigComp
    <SmallComp />
  </div>
);

SmallComp.tsx // 内层组件

import React from 'react';
import { ThemeContext } from './theme';

export default () => {
  return (
    <ThemeContext.Consumer>
      {({ theme, changeTheme }) => (
        <div
          onClick={() => {
            changeTheme();
          }}
        >
          this is small components. theme:{theme}
        </div>
      )}
    </ThemeContext.Consumer>
  );
};

API(参考官网文档

官网文档已经写的非常清晰明了,下面对文档进行举例。

createContext

创建一个 Context 对象。当我们需要取 context 的值时,会从距离组件树最近的 Provider 中读取到当前的 context 值。

只有当组件所处的树中没有匹配到 Provider 时,其 defaultValue 参数才会生效。

Provider

Context 对象都会返回 Provider 组件。Provider 下可以包含多个消费组件(子组件)。

Provider 接收一个 value 属性。

例:<ThemeContext.Provider value={'light'}></ThemeContext.Provider>

Providervalue 值发生变化时,它内部的所有消费组件都会重新渲染。

多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据。

例:

<ThemeContext.Provider value={theme}>
    <UserContext.Provider value={signedInUser}>
      <Layout />
    </UserContext.Provider>
</ThemeContext.Provider>

Consumer

接收当前的 context 值,并返回一个 React 节点。

例子:<ThemeContext.Consumer>{value => <div></div>}</ThemeContext.Consumer>

编写不易,给个 star 再走吧~在这里插入图片描述