创建和更新 Store

创建和更新 Store 的最佳实践

封装 Store 操作(推荐)

推荐将状态修改逻辑封装在 store 里集中管理,使状态修改逻辑与组件分离,代码更清晰、易于维护。

const counterStore = createStore({
  count: 0,
  increment() {
    // 使用 store 实例直接修改状态
    counterStore.setState((state) => {
      state.count++;
    });
  },
  // 支持异步操作
  async incrementAsync() {
    await new Promise((resolve) => setTimeout(resolve, 1000));

    // 使用 store.value 访问当前状态
    const currentCount = counterStore.value.count;

    // 也可以直接调用 store 下的其他方法
    counterStore.value.increment();
  },
});

// 在组件里或任何地方都可以通过 store.value 直接调用 store 下的方法
counterStore.value.increment();
await counterStore.value.incrementAsync();

状态更新模式

首先,我们定义一个复杂的带方法的 store:

const userStore = createStore({
  name: "张三",
  followers: 0,
  settings: {
    language: "zh",
    theme: {
      primary: "blue",
    },
  },
  updateSettings(newSettings) {
    userStore.setState((state) => {
      state.settings = newSettings;
    });
  },
});

1. Immer 风格更新(推荐)

支持使用 Immer 风格进行嵌套对象的复杂更新,非常直观:

userStore.setState((state) => {
  state.followers++;
  state.settings.theme.primary = "red";
});

这样你就不用通过 store.value 访问当前状态,然后写成这样:

userStore.setState({
  ...userStore.value,
  followers: userStore.value.followers + 1,
  settings: {
    ...userStore.value.settings,
    theme: {
      ...userStore.value.settings.theme,
      primary: "red",
    },
  },
});

2. 使用 store.setState 直接赋值

const counterStore = createStore({ count: 0 });

counterStore.setState({
  count: counterStore.value.count + 1,
});

这种方式对于简单状态更新很方便,但对于复杂状态更新较为麻烦,需要手动展开整个状态。

比如,更新一个带方法的 store:

userStore.setState({
  ...userStore.value, // 展开原来的状态,包含 store 里的方法
  followers: userStore.value.followers + 1, // 更新 followers
});

3. 更新部分状态

幸运的是,ZenBox 允许你这样更新部分状态,非常方便:

userStore.setState({
  name: "李四",
  followers: userStore.value.followers + 1,
  age: 18, // 注意:新属性会被忽略,不会 merge 到当前的状态里
});

注意:

  • 只支持第一层属性的合并
  • 如果要更新嵌套状态,推荐使用 Immer 风格更新

4. 直接赋值

或者你也可以使用更直观的 store.value = x 方式更新状态。

userStore.value = {
  name: "李四",
  followers: 100,
  settings: {
    language: "zh",
    theme: {
      primary: "red",
    },
  },
};

store.setState(x) 相同,支持更新部分状态。

userStore.value = {
  name: "李四",
  followers: userStore.value.followers + 1,
};

注意:

  • 虽然部分状态更新更简洁,但理解起来更容易误解
  • 推荐使用 Immer 风格更新部分状态,更直观