react18中redux-promise搭配redux-thunk完美简化异步数据操作

用过redux-thunk的应该知道,操作相对繁琐一点,dispatch本只可以出发plain objectredux-thunkdispatch可以返回一个函数。而redux-promise在此基础上大大简化了操作。

实现效果

关键逻辑代码

  • store/index.js
js 复制代码
import { createStore, applyMiddleware } from "redux";
import { combineReducers } from "redux-immutable";
import { thunk } from "redux-thunk";
import { createLogger } from "redux-logger";
import reduxPromise from "redux-promise";
import reducer from "./reducer";

const middleware = [thunk, reduxPromise];
const env = process.env.NODE_ENV;
if (env === "development") {
  middleware.push(createLogger({ collapsed: true }));
}

const store = createStore(reducer, applyMiddleware(...middleware));

export default store;
  • reucer.js
js 复制代码
import { fromJS } from "immutable";
import { delay } from "../../utils";
const initstate = fromJS({
  list: [],
  count: 100,
});

function storeReducers(state = initstate, action) {
  console.log("🚀 ~ storeReducers ~ action:", action);
  switch (action.type) {
    case "ADD":
      return state.updateIn(["count"], (n) => n + action.value);
    case "MINUS":
      return state.updateIn(["count"], (n) => n - action.value);
    default:
      return state;
  }
}

export async function handleAdd() {
  await delay(2000);
  const data = await Promise.resolve(20);
  return { type: "ADD", value: data };
}

export async function handleMinus() {
  await delay(2000);
  const data = await Promise.resolve(20);
  return { type: "MINUS", value: data };
}

export default storeReducers;

可以发现在handleAdd里面写异步业务获取返回数据是可以正常执行的,功能完好。

当我们注释掉redux-promise中间件的配置好后,页面会立马报错。

js 复制代码
import { createStore, applyMiddleware } from "redux";
import { combineReducers } from "redux-immutable";
import { thunk } from "redux-thunk";
import { createLogger } from "redux-logger";
// import reduxPromise from "redux-promise";
import reducer from "./reducer";

// const middleware = [thunk, reduxPromise];
const middleware = [thunk];
const env = process.env.NODE_ENV;
if (env === "development") {
  middleware.push(createLogger({ collapsed: true }));
}

const store = createStore(reducer, applyMiddleware(...middleware));
export default store;
  • 组件代码
js 复制代码
import { Button, Dialog, setDefaultConfig, Space, Toast } from "antd-mobile";
import { http } from "../api/request";
import { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { handleAdd, handleMinus } from "../store/reducer/store";
function Home() {
  const count = useSelector((state) => state.getIn(["store", "count"]));
  const dispatch = useDispatch();
  function handleAddCount() {
    dispatch(handleAdd());
  }
  function handleMinusCount() {
    dispatch(handleMinus());
  }
  return (
    <div className="home-box">
      <h2>home</h2>
      <p>{count}</p>
      <Space>
        <Button color="primary" onClick={handleAddCount}>
          add
        </Button>
        <Button color="danger" onClick={handleMinusCount}>
          minus
        </Button>
      </Space>
    </div>
  );
}
export default Home;

参考资料

相关推荐
哆啦A梦15881 小时前
axios 的二次封装
前端·vue.js·node.js
阿珊和她的猫1 小时前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
yinuo1 小时前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端
snow@li2 小时前
html5:拖放 / demo / 拖放事件(Drag Events)/ DataTransfer 对象方法
前端·html·拖放
浪裡遊3 小时前
Nivo图表库全面指南:配置与用法详解
前端·javascript·react.js·node.js·php
漂流瓶jz4 小时前
快速定位源码问题:SourceMap的生成/使用/文件格式与历史
前端·javascript·前端工程化
samroom4 小时前
iframe实战:跨域通信与安全隔离
前端·安全
fury_1235 小时前
vue3:数组的.includes方法怎么使用
前端·javascript·vue.js
weixin_405023375 小时前
包资源管理器NPM 使用
前端·npm·node.js
宁&沉沦5 小时前
Cursor 科技感的登录页面提示词
前端·javascript·vue.js