当你需要进行 Redux 和 React Query 的组合时,除了常规的 Redux 方法(例如手动派发 action 和更新 state),还可以使用 createSlice
和 React Query 进行组合,这可以让你更方便地封装异步请求和更容易地更新状态。
使用 createSlice
创建 reducer:
javascript
import { createSlice } from '@reduxjs/toolkit';
import { fetchUserInfo, fetchUserList } from './api';
import { useQuery } from 'react-query';
const userSlice = createSlice({
name: 'users',
initialState: {
userInfo: null,
userList: null,
},
reducers: {
setUserInfo: (state, action) => {
state.userInfo = action.payload;
},
setUserList: (state, action) => {
state.userList = action.payload;
},
},
});
export const { setUserInfo, setUserList } = userSlice.actions;
export const useUserInfoQuery = (userId) => {
const { data, isLoading, isError } = useQuery(['userInfo', userId], () => fetchUserInfo(userId));
if (data) {
dispatch(setUserInfo(data));
}
return {
user: useSelector((state) => state.users.userInfo),
isLoading,
isError,
};
};
export const useUserListQuery = () => {
const { data, isLoading, isError } = useQuery('userList', fetchUserList);
if (data) {
dispatch(setUserList(data));
}
return {
userList: useSelector((state) => state.users.userList),
isLoading,
isError,
};
};
export default userSlice.reducer;
接着,在 store 中注册 userReducer
reducer,并添加 React Query Provider,这样可以在整个应用程序中共享 React Query 的 cache,避免重复的请求。
javascript
import { configureStore } from '@reduxjs/toolkit';
import { QueryClient, QueryClientProvider } from 'react-query';
import { Provider } from 'react-redux';
import userReducer from './userSlice';
const queryClient = new QueryClient();
const store = configureStore({
reducer: {
users: userReducer,
},
});
ReactDOM.render(
<Provider store={store}>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</Provider>,
document.getElementById('root')
);
最后,在组件中使用创建的 useUserInfoQuery
和 useUserListQuery
hooks,展示用户信息和用户列表。
javascript
import { useUserInfoQuery, useUserListQuery } from './userSlice';
const UserInfo = ({ userId }) => {
const { user, isLoading, isError } = useUserInfoQuery(userId);
if (isLoading) {
return <div>Loading</div>;
}
if (isError) {
return <div>Error</div>;
}
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
<p>{user.phone}</p>
</div>
);
};
const UserList = () => {
const { userList, isLoading, isError } = useUserListQuery();
if (isLoading) {
return <div>Loading</div>;
}
if (isError) {
return <div>Error</div>;
}
return (
<div>
{userList.map(user => (
<div key={user.id}>
<h2>{user.name}</h2>
<p>{user.email}</p>
<p>{user.phone}</p>
</div>
))}
</div>
);
};
通过使用 createSlice
和 React Query 结合的方式,不仅可以更轻松管理 Redux 的异步状态和数据请求,也更方便地管理用户的相关状态信息。