Dva: reducers和effects 名称不能一样吗,相同reduces 不执行

Created on 28 Dec 2017  ·  10Comments  ·  Source: dvajs/dva

Code to reproduce the issue: (请提供可复现的代码或者步骤)

export default {
  namespace: 'project',
  state: {
    fetching: false
  },
  reducers: {
    getGroup(state, { payload }) {// not executed
      return { ...state, ...payload, fetching: false };
    },
  },
  effects: {
    *getGroup({ payload: { dir } }, { call, put }) {  // eslint-disable-line
      const getGroupRes = yield call(projectService.getGroup, { dir });
      yield put(createAction('getGroup')({ getGroupRes }));
    },
  },

Expected behavior: (预期的正常效果)

Actual behavior: (实际效果)

Versions of packages used: (哪个库的哪个版本出现的问题)

"dva": "^2.1.0",

Most helpful comment

@hengkx @zhuyangbing 你们说的这个问题确实存在,之所以 1.x可以,2.x就不行是因为 在 2.x 版本中增加了一个 promiseMiddleware 的中间件,这个中间件对 action.type 进行匹配,如果判断是 effects 就会 返回一个 promise 然后 等待 saga 执行完成,对该 promise 进行决议,所以对于 同样名称的 reducers 就会忽略掉(因为是一个if...else判断逻辑)。
对于该问题有两种解决方案:
1、可以在 promiseMiddleware 中判断 isEffect 的逻辑中同时去判断该 action.type 是否匹配 reducers,如果匹配直接报异常,提示reducers 和 effects 不能有相同的 名称
2、增加一个 判断是否是 reducers 的方法 isReducer ,在 对 effects 进行包装 promise 的逻辑中判断如果是 reducers 则 同时调用 next(action) 确保 reducer 也可以对该 action 进行处理。

@sorrycc 看看该使用哪一个解决方案,我会提交一个 PR.

All 10 comments

我也遇到了,1.x可以,2.x就不行,不知道怎么解决.

这是bug 还是有什么原因的

入口同名只能选其中一个.这样做的目的是什么呢.起两个不一样的名称就行了.

@hengkx @zhuyangbing 你们说的这个问题确实存在,之所以 1.x可以,2.x就不行是因为 在 2.x 版本中增加了一个 promiseMiddleware 的中间件,这个中间件对 action.type 进行匹配,如果判断是 effects 就会 返回一个 promise 然后 等待 saga 执行完成,对该 promise 进行决议,所以对于 同样名称的 reducers 就会忽略掉(因为是一个if...else判断逻辑)。
对于该问题有两种解决方案:
1、可以在 promiseMiddleware 中判断 isEffect 的逻辑中同时去判断该 action.type 是否匹配 reducers,如果匹配直接报异常,提示reducers 和 effects 不能有相同的 名称
2、增加一个 判断是否是 reducers 的方法 isReducer ,在 对 effects 进行包装 promise 的逻辑中判断如果是 reducers 则 同时调用 next(action) 确保 reducer 也可以对该 action 进行处理。

@sorrycc 看看该使用哪一个解决方案,我会提交一个 PR.

reducer命名为setGroup不是更加清晰吗,我觉得应该尽量避免使用重复的名字。我倾向于方案1

两个不同概念的命名,为什么要求不能重名?

我个人也更倾向于第一种方案, effects 和 reducers 所做的事情是不同的, 并不应该用同一个名称

我这个vuex用多了,经常用相同名字,加上编译慢,卡了我许久。

其实这个问题 @sorryccdva 2.0 升级说明里就提到了,我们粗心没有看到,还以为是 bug : (

@hengkx @zhuyangbing 你们说的这个问题确实存在,之所以 1.x可以,2.x就不行是因为 在 2.x 版本中增加了一个 promiseMiddleware 的中间件,这个中间件对 action.type 进行匹配,如果判断是 effects 就会 返回一个 promise 然后 等待 saga 执行完成,对该 promise 进行决议,所以对于 同样名称的 reducers 就会忽略掉(因为是一个if...else判断逻辑)。
对于该问题有两种解决方案:
1、可以在 promiseMiddleware 中判断 isEffect 的逻辑中同时去判断该 action.type 是否匹配 reducers,如果匹配直接报异常,提示reducers 和 effects 不能有相同的 名称
2、增加一个 判断是否是 reducers 的方法 isReducer ,在 对 effects 进行包装 promise 的逻辑中判断如果是 reducers 则 同时调用 next(action) 确保 reducer 也可以对该 action 进行处理。

@sorrycc 看看该使用哪一个解决方案,我会提交一个 PR.

@sorrycc 第一次写 dva,就搞了个死循环,这种框架底层能直接抛错出来嘛?

Was this page helpful?
0 / 5 - 0 ratings