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

React:让Context Provider全权处理异步调用与状态管理,消费者无需维护状态

实现无需Consumer管理状态的异步Feature Flag Provider/Consumer模式

核心思路

让Provider统一维护所有Feature Flag的加载状态和最终值,通过自定义hook封装状态获取与异步加载逻辑,Consumer只需调用hook获取状态,无需处理任何异步或状态管理代码。

实现代码

1. 重构Context Provider

import { createContext, useContext, useState, useCallback } from 'react';

// 初始化Context
const FeaturesContext = createContext();

export function FeaturesProvider({ children }) {
  // 状态结构:{ [flagKey]: { loading: boolean, value: boolean } }
  const [featureFlags, setFeatureFlags] = useState({});

  // 封装异步加载Feature Flag的逻辑
  const loadFeatureFlag = useCallback(async (key) => {
    // 避免重复请求:已加载或正在加载时直接返回
    const existingFlag = featureFlags[key];
    if (existingFlag?.loading || existingFlag?.value !== undefined) return;

    // 标记为加载中
    setFeatureFlags(prev => ({
      ...prev,
      [key]: { loading: true, value: undefined }
    }));

    try {
      // 调用你的异步评估函数
      const result = await evaluateFeatureFlag(key);
      setFeatureFlags(prev => ({
        ...prev,
        [key]: { loading: false, value: result }
      }));
    } catch (err) {
      console.error(`加载Feature Flag ${key}失败:`, err);
      // 出错时默认设为禁用,可根据需求调整
      setFeatureFlags(prev => ({
        ...prev,
        [key]: { loading: false, value: false }
      }));
    }
  }, [featureFlags]);

  return (
    <FeaturesContext.Provider value={{ featureFlags, loadFeatureFlag }}>
      {children}
    </FeaturesContext.Provider>
  );
}

2. 封装自定义Hook供Consumer使用

// 自定义Hook,简化Consumer调用
export function useFeatureFlag(key) {
  const { featureFlags, loadFeatureFlag } = useContext(FeaturesContext);
  // 默认状态:未加载时loading为false,value为undefined
  const currentFlag = featureFlags[key] || { loading: false, value: undefined };

  // 首次使用该Flag时触发加载
  useState(() => {
    if (!featureFlags[key]) {
      loadFeatureFlag(key);
    }
  }, [key, featureFlags, loadFeatureFlag]);

  return {
    loading: currentFlag.loading,
    isEnabled: currentFlag.value
  };
}

3. Consumer组件使用示例

import { useFeatureFlag } from './FeaturesProvider';

function MyCoolFeature() {
  const { loading, isEnabled } = useFeatureFlag('My_cool_feature');

  // 加载中状态可自定义展示(比如骨架屏、加载提示)
  if (loading) {
    return <div>加载中...</div>;
  }

  return isEnabled ? <div>展示功能内容</div> : <div>功能已隐藏</div>;
}

优势说明

  • 状态完全集中管理:所有异步请求、状态更新都在Provider中处理,Consumer无需编写useEffect或useState。
  • 自动缓存与去重:已加载的Flag会被缓存,重复调用不会触发多次请求。
  • 清晰的状态反馈:通过loading状态可优雅处理加载过程,避免组件渲染异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 15:42:26