首页 > 解决方案 > Redux 的 Store.dispatch 没有更新的问题

问题描述

升级meteor(从 1.4 到 1.7)和react(从 15.3.2 到 16.8.6)。

"react-redux": "^4.4.10"
"redux": "3.5.2"

我发现我的代码无法使用 Store.dispatch() 更新/存储,商店只是没有更新。

我的 ACTIONS 文件如下:

动作/config.js

...
export default {
  load({Meteor, Store}) {
    return new Promise((resolve, reject) => {
      Meteor.call('variables.load', null, (err, data) => {
        if (err) {
          reject({_error: err.reason });
          return;
        }

console.log("************ Store (A) = "+JSON.stringify(Store.getState()))
        Store.dispatch({
          type: LOAD_CONFIG,
          data
        });

        resolve();
console.log("************ Store (B) = "+JSON.stringify(Store.getState()))
      });
    });
  },
...

两个 console.log() 都具有以下内容:

Store (A) = {"router":{"locationBeforeTransitions":{"pathname":"/settings/config","search":"","hash":"","action":"PUSH","key":"zif4ls","basename":"/crm","query":{}}},"form":{"config":{"syncErrors":{"reportLimit":"Required"}}},"loadingBar":{}}

Store (B) = {"router":{"locationBeforeTransitions":{"pathname":"/settings/config","search":"","hash":"","action":"PUSH","key":"zif4ls","basename":"/crm","query":{}}},"form":{"config":{"syncErrors":{"reportLimit":"Required"}}},"loadingBar":{}}

我确实希望它会有类似的东西"reportLimit":6,它已被确认已加载到data变量中。相反,我在浏览器控制台中收到以下错误:

Uncaught TypeError: Cannot read property 'data' of undefined

你能想到什么错误/破坏性的变化吗?因为这些代码在升级之前一直在工作。


编辑:

我进一步缩小了问题的范围。似乎我的 Routes 没有调用 Reducer。

我已经更改了我的 Routes 中的代码以消除使用 require.ensure 的需要。

routes.jsx(之前)

 {
     path: 'config',
     getComponent(nextState, cb) {
         require.ensure([], (require) => {
           Store.injectReducer('config', require('./reducers').config)
           cb(null, require('./containers/config.js'))
         }, 'config')
     }
 },

routes.jsx(最新,摆脱require.ensure

 {
      path: 'config',
      getComponent(nextState, cb) {
      import('./containers/config.js')
      .then(mod => {Store.injectReducer('config', require('./reducers').config); 
      cb(null, mod);});
      }
 },

然后我注意到在减速器中:

减速器/config.js

// ------------------------------------
// Action Handlers
// ------------------------------------
const ACTION_HANDLERS = {
    [LOAD_CONFIG]: (state, action) => ({
      ...state,
      data: action.data
    })
};

// ------------------------------------
// Reducer
// ------------------------------------
const initialState = {
    data: null
};

export default function configReducer(state = initialState, action) {
console.log("************ Reducer")
    const handler = ACTION_HANDLERS[action.type];

    return handler ? handler(state, action) : state;
}

根据记录,函数configReducer似乎没有在其他地方被调用。

标签: reduxreact-redux

解决方案


经过多次反复试验,确认问题出在路由部分,最终更改:

routes.jsx(最终版)

{
    path: 'config',
    getComponent(nextState, cb) {
        import('./containers/config').then(mod => {
            Store.injectReducer('config', require('./reducers/config').default);
            cb(null, mod.default);
        });
    }
}

关键点:1)这是如何从require.ensure(由 webpack 使用)迁移到不依赖 webpack(这是我的情况,因为我完全使用 Meteor Atmosphere 运行)2)modrequire(...).xxx已更改为mod.defaultrequire(...).default如果reducer函数导出为export default,否则说reducer不会叫。

真的花了我几个星期才弄清楚这一点!


推荐阅读