createProvider

创建组件隔离的 store,适用于局部状态管理

何时使用 Provider

适用于需要按组件实例隔离的状态:

  • 模态框或对话框状态
  • 不应持久化的表单状态
  • 不应全局化的功能特定状态

API 参考

语法

const [Provider, useFindStore, storeActions] = createProvider(initialState);

参数

  • initialState: 定义 store 初始状态和操作的对象

返回值

包含以下内容的元组:

  • Provider: 为子组件提供隔离 store 实例的 React 组件
  • useFindStore: 在 provider 树中访问 store 实例的 hook
  • storeActions: 包含 getStoregetStatesetState 方法的工具对象

示例

简单隔离状态

import { createProvider, useStoreValue } from "zenbox";

// 为每个 provider 创建隔离的会话状态
const [SessionProvider, useFindSessionStore] = createProvider({
  user: null,
  isAuthenticated: false,
  sessionId: null,
  preferences: {
    theme: "light",
    language: "zh",
  },
});

function UserProfile() {
  const store = useFindSessionStore();
  const { user, isAuthenticated } = useStoreValue(store);

  if (!isAuthenticated) {
    return <div>请登录</div>;
  }

  return (
    <div>
      <h1>欢迎,{user.name}!</h1>
      <p>会话ID: {store.value.sessionId}</p>
    </div>
  );
}

function App() {
  return (
    <SessionProvider initialState={{ sessionId: "abc123" }}>
      <UserProfile />
    </SessionProvider>
  );
}

带操作的 Provider

const [GameProvider, useFindGameStore, gameActions] = createProvider({
  // 状态
  score: 0,
  level: 1,
  lives: 3,
  gameState: "playing" as "playing" | "paused" | "gameOver",

  // 操作
  increaseScore(points) {
    gameActions.setState((state) => {
      state.score += points;
      // 每1000分自动升级
      if (state.score >= state.level * 1000) {
        state.level += 1;
      }
    });
  },

  loseLife() {
    gameActions.setState((state) => {
      state.lives -= 1;
      if (state.lives <= 0) {
        state.gameState = "gameOver";
      }
    });
  },

  resetGame() {
    gameActions.setState((state) => {
      state.score = 0;
      state.level = 1;
      state.lives = 3;
      state.gameState = "playing";
    });
  },
});

function GameComponent() {
  const store = useFindGameStore();
  const { score, level, lives, gameState } = useStoreValue(store);

  return (
    <div className="game">
      <div className="hud">
        <span>得分: {score}</span>
        <span>等级: {level}</span>
        <span>生命: {lives}</span>
      </div>

      {gameState === "gameOver" ? (
        <div className="game-over">
          <h2>游戏结束!最终得分: {score}</h2>
          <button onClick={store.value.resetGame}>重新开始</button>
        </div>
      ) : (
        <div className="game-area">
          <button onClick={() => store.value.increaseScore(100)}>
            +100 分
          </button>
          <button onClick={store.value.loseLife}>失去生命</button>
        </div>
      )}
    </div>
  );
}

// 多个独立的游戏实例
function App() {
  return (
    <div className="app">
      <h1>游戏竞技场</h1>

      <div className="games">
        <GameProvider>
          <h2>玩家 1</h2>
          <GameComponent />
        </GameProvider>

        <GameProvider>
          <h2>玩家 2</h2>
          <GameComponent />
        </GameProvider>
      </div>
    </div>
  );
}

嵌套 Provider

function App() {
  return (
    <SessionProvider>
      <GameProvider>
        <GameComponent />
      </GameProvider>
    </SessionProvider>
  );
}

Provider vs 全局 Store

特性createProvidercreateStore
作用域组件树全局应用
隔离性✅ 完全隔离❌ 应用间共享
上下文✅ React Context❌ 直接访问
多实例✅ 独立❌ 单一实例
适用于模态框、表单、组件应用状态、用户数据

最佳实践

用于真正隔离的状态

// Good:弹窗状态不应在实例间共享
const [ModalProvider, useModal] = createProvider({
  isOpen: false,
  step: 1,
});

使用有意义的默认值初始化

<GameProvider initialState={{
  difficulty: "hard",
  playerName: "匿名"
}}>

保持 provider 专注

// Good:单一职责
const [FormProvider, useForm] = createProvider({
  values: {},
  errors: {},
  isSubmitting: false,
});

不要用于全局状态

// Bad:用户认证应该是全局的,无需使用 provider 隔离
const [AuthProvider] = createProvider({
  currentUser: null,
});

相关 API