在 XState FSM 中使用外部数据

Use external data in XState FSM

我正在尝试将 XState 填充到现有的状态管理系统中(在 React 应用程序中),并且我正在尝试弄清楚如何在不重复的情况下表示已经在遗留状态管理中捕获的状态。

import {useLegacyState} from 'legacy-state-system'
import {useMachine} from '@xstate/react'
import {MyMachine} from '../machine'

const MyComponent = () => {
  const [data, setData] = useLegacyState();
  const [state, send] = useMachine(MyMachine)

  .....JSX etc....
}

有些数据没有重叠,但至少在一种情况下(选择屏幕上的项目,导致应用 send({type: "SELECT_ITEM", itemId: "xyz"}) 并触发 setData("XYZ")),旧版和新版系统关心该项目。 XState 用于 UI 状态管理,但遗留系统有依赖于其内部状态的副作用,所以我不能只在 XState 中有数据。

我对 XState 的理解是,我应该将 itemId 表示为 XState 上下文中的连续数据,但这会重复数据,我担心这会带来维护问题,因为所有开发人员永远都需要知道同时更新。有没有办法让 XState Context 从运行时评估的函数中获取值?我知道 assign 如果我想将值推送到 Context 但这很容易受到相同维护问题的影响,所以我正在寻找一种方法来在我调用 state.context.itemId 时从 legacy-state-manager 中提取值.

包装 useMachine 并改用它怎么样?

import { useMachine as useXStateMachine } from '@xstate/react'

export const useMachine = (machine, options) => {
  const [data, setData] = useLegacyState();
  const [state, send] = useXStateMachine(machine)

  const context = new Proxy({}, {
    get: (_, prop) => {
      try {
        return state.context[prop] || data[prop]
      } catch (_) {
        return data[prop]
      }
    }
  })

  return [{...state, context}, send]
}

每次数据存储更改并呈现时,视图或反应层都会更新。通常在 MVC 架构中,这些逻辑被内置到控制器中,多个数据存储在控制器中组合在一起,结果数据被 returned 到 UI。在基于钩子的方法中,就像您使用的那样,您创建服务,将数据存储逻辑包装在其中,并且 return 仅 UI 级别所需的数据。

从“./services”导入{useCustomService};

const MyComponent = () => {
  const [uiData, updateUI] = useCustomService();
}