react-redux的actions如何兼容异步方法

1,003 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情

前言

最近在新项目要使用react-redux,然后发现actions的方法使用异步方法会报错。这篇文章记录如何解决这个的。

问题

我使用的主要依赖版本

    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "react-redux": "^8.0.2",
    "react-scripts": "5.0.1",
    "redux": "^4.2.0",

正常actions应该是同步函数的

const SYNC = 'SYNC'
export function syncFn (text) {
  return {
    type: SYNC,
    text
  }
}
const mapDispatchToProps = (dispatch) => {
  return {
    syncFn: async () => dispatch(syncFn())
  }
}

在页面那里定义mapDispatchToProps函数,内部通过dispatch触发actions的syncFn方法。

正常是没有问题的。

但是我这边需要在action里面添加请求,因为请求是异步的,也就是要把syncFn变成是异步方法。

然后就改成如下:加了async标识

const ASYNC = 'ASYNC'
export async function asyncFn (text) {
  return {
    type: SYNC,
    text
  }
}

然后一执行,就报错了。如下:

image.png

说actions必须是简单对象,不能是其它对象,我把它设置成premise对象,所以就报错了。

解决

我跟着报错后面的2个提示链接去尝试,发现安装了依赖(redux-thunk,redux-devtools-extension)还是不能解决问题,问题还是存在。

image.png

然后去网上查看,网上的例子跟我的情况不尽相同,所以它们的解决方案就无法适用。

思索无果,我就自己琢磨。

因为调用mapDispatchToProps函数的时候,内部是通过dispatch去触发action的方法的,所以应该是dispatch在action的方法执行后判断如果返回值不是简单对象,就会报错。

因为异步函数执行后还是Promise,不是简单对象,所以就报错了。

所以不能把异步函数传给dispatch。 我们可以加个await去执行异步函数,这样它返回就是简单对象了。

代码如下:

const mapDispatchToProps = (dispatch) => {
  return {
    asyncFn: async () => dispatch(await asyncFn())
  }
}
const ASYNC = 'ASYNC'
export async function asyncFn (text) {
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve()
    }, 3000)
  })
  return {
    type: ASYNC,
    text
  }
}

这样执行就不会报错了,同时也实现了异步的效果, 3s后才会执行actions的type。

大家如果有其它方法,欢迎评论。