状态机将系统建模为一组有限的状态加上它们之间允许的转换。与其处理独立的 boolean 标志,不如精确定义存在哪些状态以及哪些转换是合法的——使不可能的状态变为不可表示的。
问题:boolean 混乱
js
[isLoading, setLoading] = ();
[isError, setError] = ();
[isSuccess, setSuccess] = ();
使用独立标志,没有任何东西可以阻止矛盾的组合,并且您必须在每次转换时手动保持它们一致——这是一个错误的温床。
States: idle → loading → success
↓
error → (retry) → loading
Only defined transitions are allowed; you can't be in two states at once.
const machine = {
idle: { FETCH: "loading" },
loading: { SUCCESS: "success", ERROR: "error" },
success: { FETCH: "loading" },
error: { RETRY: "loading" },
};
function transition(current, event) {
return machine[current][event] ?? current; // only legal transitions happen
}
单个 state 变量保存当前状态;一个 event 触发一个定义好的转换。非法转换(例如空闲时 SUCCESS)根本无法发生——不可能的状态通过设计已经消除。
// libraries like XState formalize this with guards, actions, nested/parallel states
const toggleMachine = createMachine({
initial: "inactive",
states: {
inactive: { on: { TOGGLE: "active" } },
active: { on: { TOGGLE: "inactive" } },
},
});
✓ Complex flows with many states: checkout, multi-step forms/wizards, media players
✓ Authentication flows (logged out → logging in → logged in → refreshing)
✓ Anything where invalid state combinations cause bugs
✗ Overkill for simple toggles or trivial state
状态机通过使无效状态变为不可能并且转换显式化来为复杂的有状态逻辑带来严谨性——用清晰、详尽的模型替代脆弱的 boolean 组合。
它们对于复杂的流程(向导、支付、身份验证、媒体)特别有价值,这些流程中 boolean 混乱导致细微的、难以重现的错误。
即使非正式地(一个 status 枚举)这个想法也改进了异步状态;正式地(XState)它提供了可视化、可测试、健壮的逻辑。
知道何时使用它们是成熟状态设计的标志。