在 Zustand 中处理异步操作的方法:
- 基本异步操作:
import { create } from 'zustand';
const useStore = create((set, get) => ({
// 状态
user: null,
loading: false,
error: null,
// 异步操作
fetchUser: async (userId) => {
try {
set({ loading: true, error: null });
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
set({ user: userData, loading: false });
} catch (err) {
set({ error: err.message, loading: false });
}
},
// 另一种方式:使用 get 获取最新状态
updateUserProfile: async (updates) => {
try {
set({ loading: true, error: null });
const currentUser = get().user;
const response = await fetch(`/api/users/${currentUser.id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(updates)
});
const updatedUser = await response.json();
set({ user: updatedUser, loading: false });
} catch (err) {
set({ error: err.message, loading: false });
}
}
}));
- 使用 Promise 链:
const useStore = create((set) => ({
data: null,
status: 'idle', // idle, loading, success, error
fetchData: () => {
set({ status: 'loading' });
return fetch('/api/data')
.then((response) => response.json())
.then((data) => {
set({ data, status: 'success' });
return data;
})
.catch((error) => {
set({ error: error.message, status: 'error' });
throw error;
});
}
}));
- 结合 React Query 或 SWR:
// 可以在 Zustand 中存储查询结果,同时使用 React Query 处理缓存和失效
import { create } from 'zustand';
import { useQuery } from 'react-query';
const useStore = create((set) => ({
user: null,
setUser: (user) => set({ user })
}));
// 在组件中
function UserProfile({ userId }) {
const { data, isLoading, error } = useQuery(
['user', userId],
() => fetch(`/api/users/${userId}`).then(res => res.json())
);
// 当查询成功时,更新 Zustand store
React.useEffect(() => {
if (data) {
useStore.getState().setUser(data);
}
}, [data]);
// 使用 Zustand 中的用户数据
const user = useStore(state => state.user);
return (
<div>
{isLoading && <p>Loading...</p>}
{error && <p>Error: {error.message}</p>}
{user && <p>User: {user.name}</p>}
</div>
);
}
关键点:
- Zustand 支持直接在 store 方法中使用 async/await
- 可以在异步操作中管理 loading 和 error 状态
- 使用
get() 获取最新状态,避免闭包陷阱
- 可以返回 Promise 以便在组件中处理异步操作的结果
- 可以与 React Query 或 SWR 等库结合使用,获得更好的缓存和失效策略