# @cassiozen/usestatemachine 中文文档

规范地址：https://npmcn.com/package/%40cassiozen/usestatemachine/

版本：1\.0\.1
npm 元数据更新时间：2022-04-04T22:03:15.136Z
中文译文更新时间：2026-11-09T04:16:15.125Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40cassiozen/usestatemachine
原文对照：https://npmcn.com/package/%40cassiozen/usestatemachine/?lang=original

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

- 包体积（解压后）：162 kB，17 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=10
- 运行依赖：0 个
- peer 依赖：react \>=16\.8\.0
- 首次发布：2021-04-29T17:39:08.694Z
- 最新版本发布：2022-01-15T00:08:34.460Z
- 近 30 天下载量：34418（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：14（近 12 个月 0 个）

## 中文简介

![](https://user-images.githubusercontent.com/33676/111815108-4695b900-88a9-11eb-8b61-3c45b40d4df6.png)

## 安装

```sh
npm install @cassiozen/usestatemachine
```

也可以使用：`pnpm add @cassiozen/usestatemachine`、`yarn add @cassiozen/usestatemachine`、`bun add @cassiozen/usestatemachine`

## README

![](https://user-images.githubusercontent.com/33676/111815108-4695b900-88a9-11eb-8b61-3c45b40d4df6.png)

**< 1 kb 时 _状态机器_ 反应的钩子 :**

参见用户界面文件 : [使用状态机器.js.org](https://usestatemachine.js.org/)

-   包括:尽管体积很小,但使用状态机器的特性完成(输入/退出回调、守卫过渡和扩展状态 - 背景)
-   惊人的 TypeScript 体验: 专注于自动类型推论(TypeScript和JavaScript两个用户自动完成,而无需手动定义打字),同时给予您指定和扩充上下文事件类型的选择.
-   Made for React: 使用 State Machine 遵循你和你的团队已经熟悉的平庸反应模式. (库本身其实是围绕React的用法"减少使用"(Reductioner & useeffect)的薄包装

![size badge](https://user-images.githubusercontent.com/33676/126902516-51f46526-3023-43c7-afd4-17df2e89a3a1.png)

## 实例

-   国家驱动的UI(隐藏并显示基于状态的UI元素) - [代码框](https://codesandbox.io/s/github/cassiozen/usestatemachine/tree/main/examples/timer?file=/index.tsx) - 说吧 [来源](https://npmcn.com/package/%40cassiozen/usestatemachine/examples/timer)
-   Async 管弦乐( 附带有限重试的数据) - [代码框](https://codesandbox.io/s/github/cassiozen/usestatemachine/tree/main/examples/fetch?file=/index.tsx) - 说吧 [来源](https://npmcn.com/package/%40cassiozen/usestatemachine/examples/fetch)
-   随事件发送数据( 表格) - [代码框](https://codesandbox.io/s/github/cassiozen/usestatemachine/tree/main/examples/form?file=/index.tsx) - 说吧 [来源](https://npmcn.com/package/%40cassiozen/usestatemachine/examples/form)

## 安装

```bash
npm install @cassiozen/usestatemachine
```

## 样本使用

```typescript
const [state, send] = useStateMachine({
  initial: 'inactive',
  states: {
    inactive: {
      on: { TOGGLE: 'active' },
    },
    active: {
      on: { TOGGLE: 'inactive' },
      effect() {
        console.log('Just entered the Active state');
        // Same cleanup pattern as `useEffect`:
        // If you return a function, it will run when exiting the state.
        return () => console.log('Just Left the Active state');
      },
    },
  },
});

console.log(state); // { value: 'inactive', nextEvents: ['TOGGLE'] }

// Refers to the TOGGLE event name for the state we are currently in.

send('TOGGLE');

// Logs: Just entered the Active state

console.log(state); // { value: 'active', nextEvents: ['TOGGLE'] }
```

# API 密码

# 使用状态机器

```typescript
const [state, send] = useStateMachine(/* State Machine Definition */);
```

`useStateMachine` 以 JavaScript 对象作为状态机器定义 。 它返回由 A 构成的数组 `current machine state` 对象和 a `send` 函数以触发转换.

### 状态

这机器 `state` 由4个属性组成: `value`, (中文(简体) ), `event`, (中文(简体) ), `nextEvents` 财务报告和审定财务报表 `context`。 。 。 .

`value` (字符串):返回当前状态的名称.

`event` (单位:千美元)`{type: string}`; 可选 : 导致这个状态的最后一个发送事件的名称.

`nextEvents` (单位:千美元)`string[]`: 带有可用事件名称的阵列来触发此状态的过渡.

`context`:州机所延州. 见下文"外国".

### 发送事件

`send` 将一个事件作为参数,以"TOGGLE"等短手字符串格式提供,或作为事件对象(例如. `{ type: "TOGGLE" }`(中文(简体) )

如果当前状态接受此事件,并被允许(参见守护),它将改变状态机器状态并执行效果.

您也可以使用对象标记(如:. `{ type: "UPDATE" value: 10 }`) (中文(简体) ). 检查 [计划](https://npmcn.com/package/%40cassiozen/usestatemachine/#readme-schema-context--event-typing) 需要更多关于强打额外数据的信息.

# 国家机器定义

| 密钥 | 需求 | 说明 |
| --- | --- | --- |
| 动词 |  | 如果为真, 将会记录每个上下文和状态变化 。 日志信息将在生产大楼中被删除. |
| 计划 |  | 仅用于 TypeScript 。 可选的强类型上下文和事件. 更多关于计划 [下级](https://npmcn.com/package/%40cassiozen/usestatemachine/#readme-schema-context--event-typing) |
| 上下文 |  | 上下文是机器的扩展状态. 更多关于扩展状态 [下级](https://npmcn.com/package/%40cassiozen/usestatemachine/#readme-extended-state-context) |
| 初次 | \* 联合国 | 此机器应该位于初始状态节点 |
| 状态 | \* 联合国 | 定义可能的有限状态 状态机器可以进入. |

## 定义国家

有限的状态机器在任何特定时间只能存在于有限的状态之一. 随着应用程序的相互作用,事件导致其改变状态.

国家的定义是国家名称作为密钥,对象可能有两个密钥: `on` (该事件 该状态响应)和 `effect` (在进入或退出此状态时运行任意代码):

### 打开( 事件和过渡)

描述此状态对哪些事件的反应( 以及机器在发送此事件时应该向哪个状态过渡) :

```typescript
states: {
  inactive: {
    on: {
      TOGGLE: 'active';
    }
  },
  active: {
    on: {
      TOGGLE: 'inactive';
    }
  },
},
```

事件定义还可以使用扩展的,对象语法,允许对过渡进行更多的控制(如添加守护符):

```js
on: {
  TOGGLE: {
    target: 'active',
  },
};
```

#### 警卫

警卫是实际进行国家过渡之前的功能: 如果警卫返回错误,过渡将被拒绝.

```js
const [state, send] = useStateMachine({
  initial: 'inactive',
  states: {
    inactive: {
      on: {
        TOGGLE: {
          target: 'active',
          guard({ context, event }) {
            // Return a boolean to allow or block the transition
          },
        },
      },
    },
    active: {
      on: { TOGGLE: 'inactive' },
    },
  },
});
```

守护函数接收一个带有当前上下文和事件的对象. 事件参数总是使用对象格式(例如. `{ type: 'TOGGLE' }`) (中文(简体) ).

### 影响(出入境回调)

状态机器进入给定状态时会触发效应. 如果您从效果中返回一个函数, 它会在离开状态时被引用( 类似于使用效果如何在反应中起作用) .

```typescript
const [state, send] = useStateMachine({
  initial: 'active',
  states: {
    active: {
      on: { TOGGLE: 'inactive' },
      effect({ send, setContext, event, context }) {
        console.log('Just entered the Active state');
        return () => console.log('Just Left the Active state');
      },
    },
  },
});
```

效果函数接收一个对象作为参数,有四个键:

-   `send`:将一个事件作为参数,以"TOGGLE"等快手字符串格式提供,或作为事件对象(如. `{ type: "TOGGLE" }`(中文(简体) )
-   `setContext`: 以更新器函数为参数来设置新的上下文(下文更多关于上下文). 返回对象与 `send`,因此您可以设置上下文并发送单行事件.
-   `event`:引发向此状态过渡的事件. (事件参数总是使用对象格式(例如. `{ type: 'TOGGLE' }`) (中文(简体) ).
-   `context` 效果运行时的上下文.

在这个例子中,状态机器在进入错误状态时总是会发送"RETRY"事件:

```typescript
const [state, send] = useStateMachine({
  initial: 'loading',
  states: {
    /* Other states here... */
    error: {
      on: {
        RETRY: 'load',
      },
      effect({ send }) {
        send('RETRY');
      },
    },
  },
});
```

## 扩展状态( Context)

除了数量有限的州外,州机器还可以有扩展的州(称为上下文).

您可以在状态机器定义中提供初始上下文值,然后使用 `setContext` 函数在效果内改变上下文:

```js
const [state, send] = useStateMachine({
  context: { toggleCount: 0 },
  initial: 'inactive',
  states: {
    inactive: {
      on: { TOGGLE: 'active' },
    },
    active: {
      on: { TOGGLE: 'inactive' },
      effect({ setContext }) {
        setContext(context => ({ toggleCount: context.toggleCount + 1 }));
      },
    },
  },
});

console.log(state); // { context: { toggleCount: 0 }, value: 'inactive', nextEvents: ['TOGGLE'] }

send('TOGGLE');

console.log(state); // { context: { toggleCount: 1 }, value: 'active', nextEvents: ['TOGGLE'] }
```

## Schema: 背景和事件打字

TypeScript 将自动推断您的上下文类型; 事件类型会自动生成 .

不过,有些情况下你可能想要明确控制 `context` 财务报告和审定财务报表 `event` 类型 : 您可以使用 `t` 呜咽 `schema`数字 :

_已键入上下文示例_

```typescript
const [state, send] = useStateMachine({
  schema: {
    context: t<{ toggleCount: number }>()
  },
  context: { toggleCount: 0 },
  initial: 'inactive',
  states: {
    inactive: {
      on: { TOGGLE: 'active' },
    },
    active: {
      on: { TOGGLE: 'inactive' },
      effect({ setContext }) {
        setContext(context => ({ toggleCount: context.toggleCount + 1 }));
      },
    },
  },
});
```

_类型事件_

默认情况下, 所有事件都会被输入到字符串注解中( E)`send("UPDATE")`)和标注对象(`send({ type: "UPDATE"})`) (中文(简体) ).

不过,如果想要,可以增加一个已经输入的事件,以包含任意数据(这可以用来提供在效果内部使用的值或更新上下文). 示例

```typescript
const [machine, send] = useStateMachine({
  schema: {
    context: t<{ timeout?: number }>(),
    events: {
      PING: t<{ value: number }>()
    }
  },
  context: {timeout: undefined},
  initial: 'waiting',
  states: {
    waiting: {
      on: {
        PING: 'pinged'
      }
    },
    pinged: {
      effect({ setContext, event }) {
        setContext(c => ({ timeout: event?.value ?? 0 }));
      },
    }
  },
});

send({ type: 'PING', value: 150 })
```

**说明** 你不需要在计划中宣布你的所有事件, 只有那些你正在添加任意的键和值.

# 维基

-   [从0.x.x版本更新到1.0版本](https://github.com/cassiozen/useStateMachine/wiki/Updating-from-0.X.X-to-1.0.0)
-   [捐款](https://github.com/cassiozen/useStateMachine/wiki/Contributing-to-useStateMachine)
-   [与 X 状态的比较](https://github.com/cassiozen/useStateMachine/wiki/XState-comparison)
-   [源代码走过视频](https://github.com/cassiozen/useStateMachine/wiki/Source-code-walkthrough-video)
-   [使用预告](https://github.com/cassiozen/useStateMachine/wiki/Usage-with-Preact)

# 贡献者

感谢这些伟大的人[emoji 密钥](https://allcontributors.org/docs/en/emoji-key):

<table><tbody><tr><td align="center"><a href="http://youtube.com/ReactCasts" rel="nofollow noopener noreferrer"><img alt="" src="https://avatars.githubusercontent.com/u/33676?v=4?s=100" width="100px;" loading="lazy" decoding="async" referrerpolicy="no-referrer"><br><sub><b>Cass</b></sub></a><br><a href="https://github.com/cassiozen/useStateMachine/commits?author=cassiozen" title="Code" rel="nofollow noopener noreferrer">💻</a> <a href="https://github.com/cassiozen/useStateMachine/commits?author=cassiozen" title="Documentation" rel="nofollow noopener noreferrer">📖</a> <a href="https://github.com/cassiozen/useStateMachine/commits?author=cassiozen" title="Tests" rel="nofollow noopener noreferrer">⚠️</a> <a href="https://npmcn.com/package/%40cassiozen/usestatemachine/#readme-ideas-cassiozen" title="Ideas, Planning, &amp; Feedback" rel="nofollow noopener noreferrer">🤔</a> <a href="https://github.com/cassiozen/useStateMachine/issues?q=author%3Acassiozen" title="Bug reports" rel="nofollow noopener noreferrer">🐛</a></td><td align="center"><a href="https://github.com/devanshj" rel="nofollow noopener noreferrer"><img alt="" src="https://avatars.githubusercontent.com/u/30295578?v=4?s=100" width="100px;" loading="lazy" decoding="async" referrerpolicy="no-referrer"><br><sub><b>德凡什·杰斯马拉尼</b></sub></a><br><a href="https://github.com/cassiozen/useStateMachine/commits?author=devanshj" title="Code" rel="nofollow noopener noreferrer">💻</a> <a href="https://github.com/cassiozen/useStateMachine/commits?author=devanshj" title="Tests" rel="nofollow noopener noreferrer">⚠️</a> <a href="https://npmcn.com/package/%40cassiozen/usestatemachine/#readme-ideas-devanshj" title="Ideas, Planning, &amp; Feedback" rel="nofollow noopener noreferrer">🤔</a> <a href="https://github.com/cassiozen/useStateMachine/issues?q=author%3Adevanshj" title="Bug reports" rel="nofollow noopener noreferrer">🐛</a></td><td align="center"><a href="https://github.com/RunDevelopment" rel="nofollow noopener noreferrer"><img alt="" src="https://avatars.githubusercontent.com/u/20878432?v=4?s=100" width="100px;" loading="lazy" decoding="async" referrerpolicy="no-referrer"><br><sub><b>迈克尔·施密特</b></sub></a><br><a href="https://github.com/cassiozen/useStateMachine/commits?author=RunDevelopment" title="Code" rel="nofollow noopener noreferrer">💻</a> <a href="https://github.com/cassiozen/useStateMachine/commits?author=RunDevelopment" title="Tests" rel="nofollow noopener noreferrer">⚠️</a> <a href="https://npmcn.com/package/%40cassiozen/usestatemachine/#readme-ideas-RunDevelopment" title="Ideas, Planning, &amp; Feedback" rel="nofollow noopener noreferrer">🤔</a></td><td align="center"><a href="https://icyjoseph.dev/" rel="nofollow noopener noreferrer"><img alt="" src="https://avatars.githubusercontent.com/u/21013447?v=4?s=100" width="100px;" loading="lazy" decoding="async" referrerpolicy="no-referrer"><br><sub><b>约瑟夫</b></sub></a><br><a href="https://github.com/cassiozen/useStateMachine/commits?author=icyJoseph" title="Code" rel="nofollow noopener noreferrer">💻</a></td><td align="center"><a href="https://github.com/mutewinter" rel="nofollow noopener noreferrer"><img alt="" src="https://avatars.githubusercontent.com/u/305901?v=4?s=100" width="100px;" loading="lazy" decoding="async" referrerpolicy="no-referrer"><br><sub><b>杰里米·麦克</b></sub></a><br><a href="https://github.com/cassiozen/useStateMachine/commits?author=mutewinter" title="Documentation" rel="nofollow noopener noreferrer">📖</a></td></tr><tr><td align="center"><a href="https://github.com/devronhansen" rel="nofollow noopener noreferrer"><img alt="" src="https://avatars.githubusercontent.com/u/20226404?v=4?s=100" width="100px;" loading="lazy" decoding="async" referrerpolicy="no-referrer"><br><sub><b>罗恩</b></sub></a><br><a href="https://github.com/cassiozen/useStateMachine/commits?author=devronhansen" title="Documentation" rel="nofollow noopener noreferrer">📖</a></td><td align="center"><a href="https://v01.io/" rel="nofollow noopener noreferrer"><img alt="" src="https://avatars.githubusercontent.com/u/32771?v=4?s=100" width="100px;" loading="lazy" decoding="async" referrerpolicy="no-referrer"><br><sub><b>克劳斯·布莱尔</b></sub></a><br><a href="https://github.com/cassiozen/useStateMachine/commits?author=klausbreyer" title="Documentation" rel="nofollow noopener noreferrer">📖</a></td><td align="center"><a href="https://linktr.ee/arthurdenner" rel="nofollow noopener noreferrer"><img alt="" src="https://avatars.githubusercontent.com/u/13774309?v=4?s=100" width="100px;" loading="lazy" decoding="async" referrerpolicy="no-referrer"><br><sub><b>亚瑟·德纳</b></sub></a><br><a href="https://github.com/cassiozen/useStateMachine/commits?author=arthurdenner" title="Code" rel="nofollow noopener noreferrer">💻</a> <a href="https://github.com/cassiozen/useStateMachine/issues?q=author%3Aarthurdenner" title="Bug reports" rel="nofollow noopener noreferrer">🐛</a> <a href="https://github.com/cassiozen/useStateMachine/commits?author=arthurdenner" title="Tests" rel="nofollow noopener noreferrer">⚠️</a> <a href="https://npmcn.com/package/%40cassiozen/usestatemachine/#readme-ideas-arthurdenner" title="Ideas, Planning, &amp; Feedback" rel="nofollow noopener noreferrer">🤔</a></td></tr></tbody></table>

本项目遵循 [全部贡献者](https://github.com/all-contributors/all-contributors) 规格。 任何捐款都欢迎!

## 常见问题

### 如何安装 @cassiozen/usestatemachine？

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

### @cassiozen/usestatemachine 支持 TypeScript 吗？

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

### @cassiozen/usestatemachine 支持 ESM 还是 CommonJS？

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

### @cassiozen/usestatemachine 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=10。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @cassiozen/usestatemachine 可以商用吗？

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

### @cassiozen/usestatemachine 的下载量有多少？

根据 npm 官方下载统计，@cassiozen/usestatemachine 在 2026/10/09 – 2026/11/07 这 30 天内被下载 34,418 次，日均约 1,147 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @cassiozen/usestatemachine 还在维护吗？

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

