You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XState状态机中始终加载Feature Flag至上下文?

解决XState状态机Hydrate时Feature Flag未加载的问题

要实现无论状态机初始化还是从保存状态恢复(hydrate)时都能加载Feature Flag并更新上下文,你可以通过以下几种方案解决根级invoke仅执行一次的问题:

方案1:事件驱动的可复用加载服务

将Feature Flag加载逻辑封装为可复用服务,同时保留根级初始化加载,并添加全局事件触发重新加载,确保hydrate后可以手动触发:

  1. 封装加载服务
const loadFeatureFlagsService = async () => {
  return await featureFlagService.load();
};
  1. 更新状态机配置
const stateMachine = createStateMachine({
  id: 'state-machine',
  context: {
    featureFlagEvaluations: {}
  },
  // 首次初始化时自动加载
  invoke: {
    src: loadFeatureFlagsService,
    onDone: {
      actions: assign((_context, event) => ({ 
        featureFlagEvaluations: event.data 
      }))
    }
  },
  // 添加全局事件,用于hydrate后手动触发加载
  on: {
    LOAD_FEATURE_FLAGS: {
      invoke: {
        src: loadFeatureFlagsService,
        onDone: {
          actions: assign((_context, event) => ({ 
            featureFlagEvaluations: event.data 
          }))
        }
      }
    }
  },
  states: {
    create: { /* ... */ },
    retrieve: { /* ... */ }
  }
});
  1. Hydrate后触发加载
// 从存储恢复状态
const savedState = JSON.parse(localStorage.getItem('stateMachineState'));
// 启动状态机并传入保存的状态
const service = interpret(stateMachine).start(savedState);
// 发送事件触发Feature Flag加载
service.send('LOAD_FEATURE_FLAGS');

这个方案既支持首次自动加载,也能在hydrate后手动触发,还支持后续需要动态刷新Feature Flag的场景(比如用户切换环境)。

方案2:外部预加载后初始化状态机

如果不需要动态刷新Feature Flag,可以将加载逻辑放在状态机外部,确保每次启动(包括hydrate)都先加载Flag,再初始化状态机:

// 预加载Feature Flag
const preloadFeatureFlags = async () => {
  return await featureFlagService.load();
};

// 初始化状态机函数
const initStateMachine = async () => {
  const flags = await preloadFeatureFlags();
  // 从存储恢复状态
  const savedState = JSON.parse(localStorage.getItem('stateMachineState'));
  
  // 合并保存的上下文与新加载的Flag
  const mergedContext = {
    ...savedState?.context,
    featureFlagEvaluations: flags
  };
  
  // 启动状态机
  const service = interpret(
    stateMachine.withContext(mergedContext)
  ).start(savedState?.value);
  
  return service;
};

// 调用初始化
initStateMachine();

这种方式更简单直接,完全绕过状态机内部的invoke限制,适合不需要动态更新Flag的场景。

方案3:异步Entry动作(XState v4.30+)

如果你的XState版本在v4.30及以上,可以使用异步entry动作,结合手动触发事件实现重复加载:

const stateMachine = createStateMachine({
  id: 'state-machine',
  context: {
    featureFlagEvaluations: {}
  },
  // 首次启动时执行异步加载
  entry: async (context, event) => {
    const flags = await featureFlagService.load();
    assign({ featureFlagEvaluations: flags })(context, event);
  },
  // 添加事件支持手动刷新
  on: {
    RELOAD_FEATURE_FLAGS: {
      actions: async (context, event) => {
        const flags = await featureFlagService.load();
        assign({ featureFlagEvaluations: flags })(context, event);
      }
    }
  },
  states: {
    create: { /* ... */ },
    retrieve: { /* ... */ }
  }
});

Hydrate后同样需要发送RELOAD_FEATURE_FLAGS事件触发加载。


内容的提问来源于stack exchange,提问作者Guilherme Gambeti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 00:30:55