状态机 UI:构建确定性、无错误的界面
了解视觉状态机如何消除不可能的 UI 状态、简化复杂的交互组件以及在 React 中创建确定性、无错误的界面。
核心要点
UI 状态机是一种数学模型,描述界面组件可以占据的所有有效状态,以及由用户事件或系统条件触发的这些状态之间的显式转换。状态机通过使“不可能的状态成为不可能”来消除整个 UI 错误类别 - 如果您的状态机禁止这种组合,则您的加载旋转器和成功复选标记不能同时出现。
状态机解决的问题
大多数 UI 错误源自可以进入逻辑上不可能的状态的组件。一个典型的例子:没有显式状态模型的表单提交按钮可以通过两个单独的布尔标志同时处于“加载”状态和“禁用”状态。状态机通过要求组件在任何时刻始终处于一个明确定义的状态来防止这种情况发生。
- “布尔标志地狱”——isLoading、isDisabled、isError、isSuccess 全部冲突
- 快速用户同时触发多个状态的竞争条件
- 动画从不正确的中间位置开始的过渡错误
- 开发人员在代码审查中跟踪 n × n 标志组合的认知负荷
核心状态机概念
状态机由一组有限的状态、可以触发转换的事件词汇表以及确定是否允许转换的保护条件组成。
州
每个状态代表组件的特定条件。数据获取组件示例:空闲、加载、成功、错误、刷新。
事件/过渡
事件触发状态变化。 “提交”将表单从空闲状态转换为加载状态。 “SUCCESS”从加载过渡到成功。 “ERROR”从加载转变为错误。
卫兵
过渡到火灾必须满足的条件。如果表单验证守卫通过,“SUBMIT”事件只能触发空闲→加载转换。
上下文/扩展状态
机器携带的辅助数据(用户输入值、错误消息、加载的数据)以及当前状态名称。
ExodeUI 中的状态机
ExodeUI提供可视化节点图状态机编辑器。您将状态绘制为圆圈,使用代表事件的标记箭头将它们连接起来,并将弹簧动画和视觉属性更改附加到每个状态。机器保存在 .exode 文件中:在 React 中,您使用 ExodeUICanvas 加载它并通过输入驱动它,在 Swift 中则通过 ExodeUIController 驱动它。
生产实施片段
import { ExodeUICanvas } from 'exodeui';
// Springs, states and timing live in the .exode file (designed in the
// editor). Your code passes inputs in and hears events back.
export function AuthFlow() {
return (
<ExodeUICanvas
src="/auth_flow.bexode"
onTrigger={(name) => console.log('ExodeUI event:', name)}
/>
);
}