【问题标题】:Redux shorthand `mapDispatchToProps` returns undefined for `async` actions / thunksRedux 简写 `mapDispatchToProps` 返回未定义的 `async` 动作/thunk
【发布时间】:2019-08-09 17:21:37
【问题描述】:

我遇到了我认为可能是错误但可能是我的理解的问题。

基本上importasync actionRedux 容器内返回未定义,但我知道导入很好(文件存在,它是正确的大小写等)。

仔细观察,当我迁移到容器中的速记对象表示法时,问题似乎已经开始,这是一个示例:

thunks.js

import { anAsyncFunc } from './anotherFile'
export const aThunk = () => async (dispatch, getState) => {
    await dispatch(anAsyncFunc)
    return dispatch(someOtherAsyncFunc)
}

containerThatDoesntWork.js

import { aThunk  } from './thunks.js'
import MyComponent from './MyComponent'

console.log(aThunk) // undefined

const mapDispatchToProps = {
    aThunk
}

containerThatDoesWork.js

import { aThunk  } from './thunks.js'
import MyComponent from './MyComponent'

console.log(aThunk) // undefined

const mapDispatchToProps = dispatch => ({
    aThunk: () => {
       console.log(aThunk) // return async function (dispatch, getState) { ... }
       return dispatch(aThunk())
    }
})

在这两种情况下,如果我在container 中的console.log(aThunk) 我得到未定义,我认为这与async 函数的模块分辨率有关?

但是,在第二个示例中,将导入显式包装在一个函数中,组件是快乐的,而简而言之,它不是(PropTypes 验证失败)。

有人知道解决这个问题的方法吗?还是对象速记符号中mapDispatchToProps 的限制?

【问题讨论】:

  • 如果你在没有async 的情况下重写你的异步操作,它会起作用吗?另外,你能验证import { aThunk } 确实导入了一些东西吗?
  • 我无法重新编写该特定操作以避免async 执行其操作,但同一组件中的其他非async 操作绑定OK。我相信导入会返回一些东西,因为它奇怪地在其他文件中工作。这很可能与import 分辨率有关,但我不知道为什么。正如我所说,我可以解决这个问题的唯一方法是将action 包装在一个显式调用调度的函数中。
  • 当意外发生时,根据定义,这意味着您的期望在某个地方是错误的。因此,仅出于调试目的,我建议您尝试本地化问题。如果aThunkundefined,当您将它提供给mapDispatchToProps 时,将更容易找到问题。如果您可以尝试从您的操作中删除 async 只是为了进行调试,它也会使问题更加具体。
  • 对不起,我应该更清楚。两个答案,1)如果我从操作中删除异步只是为了调试,它仍然不起作用。 2)如果我console.log()mapDispatchToProps之前的函数是未定义的。然而,在 working 容器版本(包装在一个函数中)中仍然是这种情况,但此时它被传递给不再定义的组件。我认为这是因为导入最终会解决?而当包裹在函数中时,函数指向变量,而不是使用函数的值?

标签: reactjs redux async-await redux-thunk


【解决方案1】:
const mapDispatchToProps = {
    aThunk
}

const mapDispatchToProps = dispatch => ({
    aThunk: () => dispatch(aThunk())
})

应该以相同的方式表现。如果mapDispatchToProps 是一个对象,属性会自动转换为() => dispatch(action)。两者都应该导致aThunk prop 返回aThunk()(dispatch) 的结果,即一个promise。

这里是a demo

named import 可以在模块范围内未定义但存在于函数范围内的唯一原因是在延迟访问依赖项时解决了循环依赖项。使用 dispatch => ... 完成的这样的函数包装依赖项是一种已知的解决循环依赖项的方法,幸运的是,mapDispatchToProps 支持它,但最好不要一开始就拥有它们,特别是如果这不是设计使然.

【讨论】:

  • 有趣的答案,我的印象是相同的,基于此处的文档:react-redux.js.org/using-react-redux/… 这引用提供对象作为替代“连接支持 mapDispatchToProps 的“对象速记”形式参数:如果你传递一个充满动作创建者的对象而不是一个函数,connect 将在内部自动为你调用 bindActionCreators。"我错过了什么吗?
  • 我修正了错字,这只是一个错字 SO 方面,不幸的是我无法发布原始代码
  • 我最初将{ aThunk } 误读为dispatch => { aThunk }。否则我看不出问题,它应该可以工作,我提供了一个演示。目前尚不清楚 I console.log(aThunk) 在容器中我未定义 发生的位置。您是否尝试在dispatch => ... 外部和内部登录以查看差异?这与 async 没有任何关系,async 只是 Promise 的语法糖。如果您有循环依赖项,则可能会发生这种情况。在问题中没有显示它们。
  • 我确实考虑过循环引用,因为这就是谷歌搜索的结果,并且会解释为什么我看不到项目中以相同方式编写的其他操作的问题。我已经尝试了循环依赖插件,但它没有显示任何东西,虽然有点奇怪。
  • @dougajmcdonald 我不认为 Redux 应该受到指责,它是无主见的,并且不会对模块的设计施加任何限制。有一张 CD 意味着您的某些模块需要分开左右。正如我所说,dispatch => ... 只是一种解决方法。它存在很好,但这并不意味着它必须被使用。
猜你喜欢
  • 2018-05-27
  • 2019-08-22
  • 2018-11-16
  • 2018-06-01
  • 2018-01-18
  • 2018-12-17
  • 2018-05-21
  • 2019-02-05
  • 1970-01-01
相关资源
最近更新 更多