Skip to content

Setup

setup的核心目的: 把「状态机的结构」和「具体执行代码」彻底分离

setup 用来集中声明“实现细节”,createMachine 只写“状态逻辑”

ts
const machine = setup({
  actions: { ... },
  guards: { ... },
  actors: { ... },
}).createMachine({ ... })

implementations

implementations 不是状态机逻辑本身,而是:

Actions:副作用(打日志、请求接口、toast、埋点)

Actors:子任务 / 异步逻辑 / 子状态机

Guards:条件判断(是否允许跳转)

Delays:延迟时间(after / delay)

它们的共同特点:

  • 不决定状态结构
  • 不影响状态之间的关系
  • 只负责“执行细节”

setup

我们可以使用setup分离逻辑和实现:

ts
import { setup } from 'xstate';

const feedbackMachine = setup({
  // Default implementations
  actions: {
    doSomething: () => {
      console.log('Doing something!');
    },
  },
  actors: {
    /* ... */
  },
  guards: {
    /* ... */
  },
  delays: {
    /* ... */
  },
}).createMachine({
  entry: { type: 'doSomething' },//当进入这个状态时,执行 setup.actions.doSomething
  // ... rest of machine config
});

const feedbackActor = createActor(feedbackMachine);

feedbackActor.start();
// logs 'Doing something!'

provide

你可以重写默认的implementations,用新的 implementations,生成一个“同结构的新 machine”。原 machine 完全不变,返回的是 一个新 machine

ts
const customFeedbackMachine = feedbackMachine.provide({
  actions: {
    doSomething: () => {
      console.log('Doing something else!');
    },
  },
});

const feedbackActor = createActor(customFeedbackMachine);

feedbackActor.start();
// logs 'Doing something else!'

使用场景

一、开发与测试环境:

ts
// dev
machine.provide({
  actions: {
    log: console.log
  }
})

// prod
machine.provide({
  actions: {
    log: sendToSentry
  }
})

二、单元测试

ts
const testMachine = machine.provide({
  actions: {
    submitForm: () => {
      // mock,不发请求
    }
  }
})