Zustand 中如何正确处理异步 action 并更新状态?

辽源 Dev 阅读 68

我最近从 Redux 切换到 Zustand,发现写异步逻辑有点懵。比如我想在组件里调用一个获取用户信息的函数,请求完之后更新 store 里的 user 字段,但不知道该怎么组织代码。

我试过直接在 store 里写 async 函数,但状态好像没及时更新。是不是得用 set 的某种特殊方式?下面是我现在的写法:

const useStore = create((set) => ({
  user: null,
  fetchUser: async () => {
    const res = await fetch('/api/user');
    const data = await res.json();
    set({ user: data }); // 这样写对吗?
  }
}));

这样写在组件里调用 useStore.getState().fetchUser() 能正常工作吗?还是说应该用别的模式?

我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
Good“翌萌
你的写法其实是对的,Zustand 确实可以直接在 store 里写 async 函数,set 的用法也没问题。

不过你提到用 useStore.getState().fetchUser() 这种方式调用,这能工作,但不会触发组件重新渲染。正确做法是在组件里把 fetchUser 这个 action 拿出来,像这样:

const useStore = create((set) => ({
user: null,
isLoading: false,
fetchUser: async () => {
set({ isLoading: true });
const res = await fetch('/api/user');
const data = await res.json();
set({ user: data, isLoading: false });
}
}));

// 在组件里这样用
function UserProfile() {
const user = useStore(state => state.user);
const fetchUser = useStore(state => state.fetchUser);

useEffect(() => {
fetchUser(); // 组件挂载时获取用户
}, [fetchUser]);

return
{user?.name}
;
}


如果你想在 fetch 完成后做点别的事儿,有两个常用方案:

一是让 fetchUser 返回 Promise,这样调用方可以 await 它:

fetchUser: async () => {
const res = await fetch('/api/user');
const data = await res.json();
set({ user: data });
return data; // 返回数据供外部使用
}

// 调用时
await useStore.getState().fetchUser();
// 或者在组件里
const fetchUser = useStore(state => state.fetchUser);
useEffect(() => {
fetchUser().then(data => {
console.log('用户数据拿到了', data);
});
}, [fetchUser]);


二是直接在 action 内部处理完成后的逻辑。

还有一点小建议:最好加个 loading 状态,这样组件里可以显示加载动画,体验更好。你代码里没加这个,我给加上去了。

总体来说你的思路没问题,就是调用方式要注意,用 hook 拿 action 而不是 getState。
点赞
2026-03-14 01:01