服务端阅读 05月29日 22:35
Zustand 中如何处理异步操作?
Zustand 的 store 就是个普通对象,create 回调里直接写 async 函数即可,不需要 thunk 之类的中间件。写法:在 create((set, get) => ({ ... })) 里定义 async action,内部 await 拿到数据后调 set({ data, loading: false })。手动管理 loading/error 状态是最常见的方式。如果嫌重复,用 zustand/middleware 的 immer 简化嵌套更新,或封装一个 createAsyncAction 工具函数统一处理 loading/success/error 三态。追问Zustand 和 Redux Toolkit 处理异步有什么区别?RTK 需要 createAsyncThunk + extraReducers 处理三态,模板代码多。Zustand 直接在 action 里 await + set,没有中间件概念,代码量少一半以上。RTK 的优势是 DevTools 自动追踪异步状态,Zustand 需要手动 devtools middleware。并发请求怎么处理?两个独立请求各自 async action 并行调用即可。如果需要等全部完成:await Promise.all([fetchA(), fetchB()])。注意竞态问题——快速切换页面时旧请求后到会覆盖新数据,用请求 ID 或 AbortController 取消旧请求。Suspense 能配合 Zustand 用吗?可以,但需要包装成 throw promise 的模式:store 里存 promise 而非数据,组件读时如果 promise 未 resolve 就 throw 出去,Suspense 捕获。推荐用 use 包(React 19 内置)或 suspend-react 简化。不过大多数项目手动 loading 状态更直观,Suspense 方案适合设计系统级别统一处理。如何做请求缓存和去重?简单方案:store 里维护 Map<cacheKey, { data, timestamp }>,action 里先查缓存未过期就直接返回。复杂场景用 SWR 或 TanStack Query 管缓存,Zustand 只管 UI 状态,职责分离更清晰。服务端渲染(SSR)时异步怎么处理?create 时传入 hydrate 数据,客户端 useEffect 里发起请求覆盖。注意避免服务端和客户端数据不一致的 hydration mismatch——初始渲染用服务端数据,客户端请求完成后 set 更新即可。