React Query + Redux toolkit 封装异步请求

当你需要进行 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 的异步状态和数据请求,也更方便地管理用户的相关状态信息。

相关推荐
衍辉channel4 小时前
衍辉AI速递 10.14|谷歌发布Gemini 4 Argon模型等9条AI资讯
javascript
vipxieliang4 小时前
JavaScript 事件循环与任务队列:从 setTimeout 到 Promise
前端·javascript
Misnearch5 小时前
React中的回调
前端·javascript·react.js
Eider19986 小时前
大模型输出格式幻觉解决思路
开发语言·前端·javascript
志尊宝7 小时前
Vue3 零基础每日笔记(085):项目上线前 Checklist——环境变量、报错监控、安全自查
前端·javascript·笔记·安全·信息可视化·echarts
志尊宝7 小时前
Vue3 零基础每日笔记(088·完结):从零到一——一个完整 Vue3 项目的成长复盘
前端·javascript·vue.js·笔记·ecmascript·#vue.js
传人once7 小时前
企业官网静态页基础结构如何搭
javascript·css
桔筐7 小时前
Vue中DOM的data-*自定义属性(dataset)与Vue data响应式变量区别详解
前端·javascript·vue.js
damoluomu7 小时前
静态站点生成器怎么选:Node.js 生态里常用的五个(番外一)
javascript·css·typescript·node.js·html
vipxieliang7 小时前
JavaScript 执行上下文与调用栈:从原理到调试实战
前端·javascript