# @air/react-memoized-context 中文文档

规范地址：https://npmcn.com/package/%40air/react-memoized-context/

版本：1\.0\.2
npm 元数据更新时间：2026-10-09T12:00:44.815Z
中文译文更新时间：2026-11-05T20:27:38.864Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40air/react-memoized-context
原文对照：https://npmcn.com/package/%40air/react-memoized-context/?lang=original
源码仓库：https://github.com/AirLabsTeam/react-memoized-context

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：34.6 kB，17 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：react \>=17，react-dom \>=17
- 首次发布：2022-08-09T13:20:08.500Z
- 最新版本发布：2025-03-04T09:37:24.475Z
- 近 30 天下载量：28236（2026-10-05 至 2026-11-03，npm 官方下载统计）
- 已发布版本数：3（近 12 个月 0 个）

## 中文简介

-   使用您的 React 上下文而不附加在消费者中的重报 - 从上下文“ 飞上” 读取值的能力 - 在回调中有用, 这样您无需将 UI 绑定到上下文值变化中, 只是为了使用回调值 - Redux- l

## 安装

```sh
npm install @air/react-memoized-context
```

也可以使用：`pnpm add @air/react-memoized-context`、`yarn add @air/react-memoized-context`、`bun add @air/react-memoized-context`

## README

# 反应被修改的背景

_用类似 Redux 的性能和模式反应上下文而不安装 Redux ._

 [![size](https://img.shields.io/npm/v/@air/react-memoized-context?color=2E77FF)](https://www.npmjs.com/package/@air/react-memoized-context)![size](https://img.shields.io/bundlephobia/min/@air/react-memoized-context)

## \* 特性

-   使用您的 React 上下文而不在消费者中附加重接
-   从上下文“ 在飞行上” 读取值的能力 - 在回调中有用, 这样您无需将 UI 绑定在一个上下文值变化中, 只是为了在回调中使用该值
-   类似 Redux 的模式( 减小、 动作和选择器)
-   以类型脚本所建

## 关于

在这里 [空运](https://air.inc/)我们需要一个方法来储存 _多个_ 复杂全局状态的实例( React Context API 做什么),但与 Redux 的性能配合. `react-memoized-context` 解决了这个问题.

### 何以不反应背景?

反应上下文提供者 _全部_ 每次是消费者 `value` 修改 - 即使组件没有在 `value` (若为物. 这会造成很多的表演问题 社区是 [尝试](https://github.com/reactjs/rfcs/pull/119) 改为 [解开](https://github.com/dai-shi/use-context-selector)我们研究了这些其他的解决方案,但它们要么还没有准备好,要么有太多的虫子,要么缺乏特征(比如在苍蝇上读取值),所以我们决定自己滚动.

### 为什么Redux不呢?

Redux 作为全局存储器, 当多个组件想要读取和写入到一个 _单人_ 集中值。 但当你想要 _多个_ 具有相同结构的全局值, Redux 并不那么灵活,因为您需要复制您的还原器、 动作和选择器。 反应上下文是不错的 因为你可以绕着另一个提供商.

## 安装

```bash
npm install --save @air/react-memoized-context
```

```bash
yarn add @air/react-memoized-context
```

## 使用量

1.  为上下文创建类型 :
    
    -   为要存储的值创建类型 :
        
        ```typescript
        export interface User {
          id: string;
          name: string;
          score: number;
        }
        
        export interface UsersTeamContextValue {
          users: User[];
        }
        ```
        
    -   创建要更新值的行动类型 :
        
        ```typescript
        export interface UsersTeamContextActions {
          addUser: (user: User) => void;
          assignScore: (userId: User['id'], score: number) => void;
        }
        ```
        
    -   为上下文创建类型 - 记得要扩展 `MemoizedContextType`数字 :
        
        ```typescript
        export interface UsersTeamContextType extends MemoizedContextType<UsersTeamContextValue>, UsersTeamContextActionsType {}
        ```
        
    -   为上下文创建默认值 :
        
        ```typescript
        export const defaultUsersTeamContextValue: UsersTeamContextType = {
          ...defaultMemoizedContextValue,
          getValue: () => ({
            users: [],
          }),
          addUser: () => {},
          assignScore: () => {},
         };
        ```
        
    -   为您的动作创建类型 - 您将使用它们来修改上下文值 :
        
        ```typescript
        export interface AddUserAction extends MemoizedContextAction {
          type: 'addUser';
          data?: { user: User };
        }
          
        export interface AssignScoreAction extends MemoizedContextAction {
          type: 'assignScore';
          data?: { userId: User['id']; score: number };
        }
          
        export type UserTeamContextActions = AddUserAction | AssignScoreAction;
        ```
        
2.  创建上下文 :
    
    ```typescript
    const UsersTeamContext = createContext<UsersTeamContextType>(defaultUsersTeamContextValue);
    
    const useUsersTeamContext = () => useContext(UsersTeamContext);
    ```
    
3.  创建您的调度方法 。 它应该像 reduux 调度一样工作 - 采取行动,修改状态值并返回一个新的状态:
    
    ```typescript
    export const usersTeamContextDispatch = (state: UsersTeamContextValue, action: UserTeamContextActions) => {
      switch (action.type) {
        case 'assignScore':
          return {
            ...state,
            users: state.users.map((user) => {
              if (user.id === action.data?.userId) {
                return {
                  ...user,
                  score: action.data?.score ?? 0,
                };
              }
              return user;
            }),
          };
        case 'addUser':
          return {
            ...state,
            users: action.data ? [...state.users, action.data.user] : state.users,
          };
      }
    };
    ```
    
4.  创建您的提供者 :
    
    ```typescript
    export const UsersTeamProvider = ({ children }: PropsWithChildren<{}>) => {
      
      const { contextValue } = useMemoizedContextProvider<UsersTeamContextValue>(
        // provide default value for your context
        {
          users: [],
        },
        usersTeamContextDispatch,
      );
    
      // create methods you want to expose to clients
      const addUser = useCallback((user: User) => contextValue.dispatch({ type: 'addUser', data: { user } }), [contextValue]);
    
      const assignScore = useCallback(
        (userId: User['id'], score: number) => contextValue.dispatch({ type: 'assignScore', data: { userId, score } }),
        [contextValue],
      );
    
      // memoize your final value that will be available for clients
      // just return what's in contextValue and add your methods
      const value = useMemo<UsersTeamContextType>(
        () => ({
          ...contextValue,
          addUser,
          assignScore,
        }),
        [addUser, assignScore, contextValue],
      );
    
      return <UsersTeamContext.Provider value={value}>{children}</UsersTeamContext.Provider>;
    };
    ```
    
5.  要从上下文中获取数据, 您需要选择 :
    
    ```typescript
    export const usersTeamUsersSelector = (state: UsersTeamContextValue) => state.users;
    ```
    
    组件中的用法 :
    
    ```typescript
    const context = useUsersTeamContext();
    // pass context to useMemoizedContextSelector
    const users = useMemoizedContextSelector(context, usersTeamUsersSelector);
    ```
    
    为了简化它,您可以创建一个助手:
    
    ```typescript
    export function useUsersTeamContextSelector<T>(selector: (st: UsersTeamContextValue) => T) {
      const context = useUsersTeamContext();
      return useMemoizedContextSelector(context, selector);
    }
    
    ```
    
    那么,来取回 `users` 从上下文可以做到:
    
    ```typescript
    const users = useUsersTeamContextSelector(usersTeamUsersSelector);
    ```
    
6.  开始用上下文!
    
    将组件与您的 `Provider` 组件,如同您在 React 语境中所做的:
    
    ```react
    <UsersTeamProvider>
        <UsersTeam name="Team 1" />
    </UsersTeamProvider>
    ```
    

````
To modify context value, use any of your actions:

```typescript
import { useUsersTeamContextSelector } from "./usersTeamContext";

const { addUser } = useUsersTeamContext()

const onClick = () => {
  addUser({ name: 'John' })
}

```

You can read context values on the fly if you need. For example, we will create a user with `users.length` as id. We can use `usersTeamUsersSelector`, but the component would be rerendered every time when any user changes. We don't want that - we need just `users` length. We could create a selector that gets users length, but again - everytime we add a user, the component will rerender. For us, it's enough to know users length by the time we create a user:
```typescript
 // get whole context value - it will not cause any rerender!
 const contextValue = useUsersTeamContext();

  const addNewUser = () => {
    // read users array when we need it
    const users = contextValue.getValue().users;
    // call addUser action to add a new user
    contextValue.addUser({ id: users.length + 1, name: userName, score: 0 });
  };
```
````

## 密码框

您可以使用代码和框播放示例 : [https://codesandbox.io/s/boring-morning-j44i9p (中文(简体) )](https://codesandbox.io/s/boring-morning-j44i9p)

## 常见问题

### @air/react-memoized-context 是什么？

使用您的 React 上下文而不附加在消费者中的重报 - 从上下文“ 飞上” 读取值的能力 - 在回调中有用, 这样您无需将 UI 绑定到上下文值变化中, 只是为了使用回调值 - Redux- l

### 如何安装 @air/react-memoized-context？

在项目目录运行 npm install @air/react-memoized-context，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（\>=17）、react-dom（\>=17）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @air/react-memoized-context 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @air/react-memoized-context 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @air/react-memoized-context 可以商用吗？

@air/react-memoized-context 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @air/react-memoized-context 的下载量有多少？

根据 npm 官方下载统计，@air/react-memoized-context 在 2026/10/05 – 2026/11/03 这 30 天内被下载 28,236 次，日均约 941 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @air/react-memoized-context 还在维护吗？

最新版本 1\.0\.2 发布于 2025/03/04（1\.7 年前）；至今共发布 3 个版本，其中过去 12 个月发布了 0 个；首次发布于 2022/08/09。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

