Methods for handling asynchronous operations in Zustand:
- Basic asynchronous operations:
import { create } from 'zustand';
const useStore = create((set, get) => ({
// State
user: null,
loading: false,
error: null,
// Asynchronous operation
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 });
}
},
// Another way: use get to get latest state
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 });
}
}
}));
- Using Promise chains:
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;
});
}
}));
- Combining with React Query or SWR:
// Can store query results in Zustand while using React Query for caching and invalidation
import { create } from 'zustand';
import { useQuery } from 'react-query';
const useStore = create((set) => ({
user: null,
setUser: (user) => set({ user })
}));
// In component
function UserProfile({ userId }) {
const { data, isLoading, error } = useQuery(
['user', userId],
() => fetch(`/api/users/${userId}`).then(res => res.json())
);
// Update Zustand store when query succeeds
React.useEffect(() => {
if (data) {
useStore.getState().setUser(data);
}
}, [data]);
// Use user data from 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>
);
}
Key points:
- Zustand supports directly using async/await in store methods
- Can manage loading and error states during asynchronous operations
- Use
get() to get the latest state and avoid closure traps
- Can return Promises to handle asynchronous operation results in components
- Can be combined with libraries like React Query or SWR for better caching and invalidation strategies