reactjs - 在 Side Effect 中使用全局化的 Redux 选择器创建循环依赖

标签 reactjs redux react-redux redux-thunk redux-saga

使用 normalizr 规范化后,我将表单数据存储在 redux 存储中。当我提交表单时,我使用 thunk 中的选择器获取非规范化数据,然后将其发送到服务器。流程如下:

rootReducer -> localReducer -> action/actionCreator -> rootReducer

rootReducer 文件中,root reducer 组成 localReducer 并包含稍后在 thunk 中使用的全局化选择器。 localReducer 文件从也包含 Action 创建者的 Action 文件中导入 Action 。 thunk Action 创建者返回一个 thunk,它使用 rootReducer 文件中的选择器检索的数据执行 api 调用,因此循环依赖。

Webpack 不能很好地处理这种循环依赖。我在 localReducer -> action/actionCreator 级别遇到运行时 Uncaught TypeError: Cannot read property 'JOB_FORM_RESET' of undefined 错误:

const jobsForm = (state = initialState, action) => {
  switch (action.type) {
    case ActionTypes.JOB_FORM_RESET:

关于如何解决这个问题有什么想法吗?

编辑

ActionTypes 被评估为 undefined 按规定工作。 ActionTypes 位于 action/actionCreator 文件中,当它第一次被 localReducer 导入时执行没有完成,因为它立即开始导入 rootReducer。为了避免无限循环,action/actionCreator 的未完成副本(其中 ActionTypes 被评估为 undefined)被提供给 localReducer.

解决方案是将 Action 和 Action 创建者放在两个不同的文件中,从而将它们分开。这将删除循环依赖,如以下流程所示:

rootReducer -> localReducer -> action
actionCreator -> rootReducer

对我来说奇怪的是,长期以来在 redux 指南中提倡将 Action 和 Action 创建者分组,而将它们分开在两个文件中感觉不太自然。

另外,redux-saga模型中没有出现这个循环问题:

rootReducer -> localReducer -> action/actionCreator
saga -> api -> rootReducer

我已经习惯了这个模型,但不敢相信 redux-thunk 模型不能解决这个问题。换句话说,说循环问题是 redux-thunk 模型的固有副作用似乎不公平。我在这里遗漏了什么吗?

您可以在这个 repo 中找到一个 MCVE .错误是不同的,但原理是一样的,是在 src/Users/actions.js 文件中导入以下内容导致的循环依赖引起的:
从 '../reducer' 导入 { getSelectedUsers };

发生的错误是No reducer provided for key "users"。只需注释上面的导入,错误就会消失。

正如我上面所描述的,这按规定工作,我担心的是 redux-thunk 模型不处理这个用例。此外,将 Action 和 Action 创建者都放在同一个文件中,然后等待循环依赖问题发生以将它们分开似乎不是可扩展的解决方案。

最佳答案

解决方案很简单:将actionTypes提取到单独的文件中,并将其导入到actions.jsreducer.js

actionTypes.js 文件:

export const SELECT_USER = 'SELECT_USER'; 导出常量 POST_USERS = 'POST_USERS';

您可以像这样一次导入所有操作

从 './actionTypes.js' 导入 * 作为 actionTypes

这里解决的问题:

https://github.com/svitekpavel/redux-thunk-globalized-selectors-cyclic-dependencies/commit/1c7f04fc5c1d4e4155891428138f8cb00412655e

另外两个建议:

  1. 将选择器提取到单独的文件
  2. 将“效果”(postUsers) 提取到 effects.js

第二个建议来自经验,redux-thunks 的教程保留在actions.js 中的这些功能(副作用)实际上是副作用而不是 Action 创建者.

如果您使用 Redux-Saga,您会很快意识到将业务逻辑(和副作用)与 Action 创建者分离是一件好事。

另外,它们是两个独立的东西:-)

关于reactjs - 在 Side Effect 中使用全局化的 Redux 选择器创建循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50297232/

相关文章:

javascript - 组件首次更新

javascript - import 在测试时返回 undefined 而不是 react 组件

javascript - JavaScript 中的下划线 "_"是什么?

javascript - React 版本的 ngForm

javascript - 无法访问模块函数中的 quill 实例

reactjs - 如何重写@devexpress/dx-react-grid-material-ui的样式?

javascript - 如何在提交时将复杂的表单对象存储到 redux 状态?

javascript - React 无状态功能组件和组件生命周期

javascript - ReactJS 中的嵌套路由

reactjs - 如何在 react 中使用history.push