Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ReplaceReducer导致意外的密钥错误_Javascript_Reactjs_Redux - Fatal编程技术网

Javascript ReplaceReducer导致意外的密钥错误

Javascript ReplaceReducer导致意外的密钥错误,javascript,reactjs,redux,Javascript,Reactjs,Redux,我有一个React应用程序,它动态加载模块,包括模块的reducer函数,然后调用Redux的replaceReducer来替换reducer。不幸的是,我得到了一个错误 在传递给createStore的initialState参数中找到意外键“bookEntry”。希望找到一个已知的reducer键:“bookList”、“root”。意外的键将被忽略 其中bookEntry是正在更换的旧减速器上的一个键。从bookEntry模块开始切换到bookList会导致此反向错误 在传递给create

我有一个React应用程序,它动态加载模块,包括模块的reducer函数,然后调用Redux的replaceReducer来替换reducer。不幸的是,我得到了一个错误

在传递给createStore的initialState参数中找到意外键“bookEntry”。希望找到一个已知的reducer键:“bookList”、“root”。意外的键将被忽略

其中bookEntry是正在更换的旧减速器上的一个键。从bookEntry模块开始切换到bookList会导致此反向错误

在传递给createStore的initialState参数中找到意外键“bookList”。希望找到一个已知的reducer键:“bookEntry”、“root”。意外的键将被忽略

下面是代码-取消注释注释的代码实际上解决了这个问题,但我猜不需要这样做

我是否对Redux做了其他错误,这使得这段代码成为必要

function getNewReducer(reducerObj){
    if (!reducerObj) return Redux.combineReducers({ root: rootReducer });

    //store.replaceReducer(function(){
    //    return {
    //        root: rootReducer()
    //    }
    //});

    store.replaceReducer(Redux.combineReducers({
        [reducerObj.name]: reducerObj.reducer,
        root: rootReducer
    }));
}
通常我们不建议您在更改路由或加载新模块时“清理”数据。这会使应用程序的可预测性降低。如果我们说的是数十万条记录,那当然。这是您计划加载的数据量吗

如果每个页面上只有几千个条目,卸载它们没有任何好处,并且与您添加到应用程序中的复杂性相关的缺点也存在。因此,请确保您正在解决一个真正的问题,而不是过早地进行优化

现在,请看警告消息。该检查在
组合减速机()
中定义。这意味着意外的状态键将被丢弃。删除管理
状态.bookEntry
bookEntry
还原程序后,新根还原程序不再识别该部分状态,并且
combineReducers()
记录了一条警告,表示将丢弃该部分状态请注意,这是一个警告,而不是错误。您的代码运行正常。我们使用
console.error()
来突出警告,但它实际上并没有抛出,所以您可以安全地忽略它

我们并不想让警告可配置,因为您实际上是在隐式删除应用程序状态的一部分。通常人们这样做是错误的,而不是故意的。因此,我们想对此提出警告。如果您想避开警告,最好是手动编写根减速机(当前由
combineReducers()
生成)。它看起来是这样的:

// I renamed what you called "root" reducer
// to "main" reducer because the root reducer
// is the combined one.
let mainReducer = (state, action) => ...

// This is like your own combineReducers() with custom behavior
function getRootReducer(dynamicReducer) {
  // Creates a reducer from the main and a dynamic reducer
  return function (state, action) {
    // Calculate main state
    let nextState = {
      main: mainReducer(state.main, action)
    };

    // If specified, calculate dynamic reducer state
    if (dynamicReducer) {
      nextState[dynamicReducer.name] = dynamicReducer.reducer(
        nextState[dynamicReducer.name],
        action
      );
    }

    return nextState;
  };
}

// Create the store without a dynamic reducer
export function createStoreWithoutDynamicReducer() {
  return Redux.createStore(getRootReducer());
}

// Later call this to replace the dynamic reducer on a store instance
export function setDynamicReducer(store, dynamicReducer) {
  store.replaceReducer(getRootReducer(dynamicReducer));
}

但是,我们推荐的模式是。

在动态加载代码时,是否有任何特定的原因要删除以前的减速器?我不太明白。一般来说,你希望旧的减速器留下来,而不是被移除。@DanAbramov-hm,没有具体的原因。我只是假设即将推出的模块会自行“清理”。这不是我在实践中应该做的吗?我是否应该发出一个调度以清除其数据,但离开减速机?什么是“清理”的目的?通常情况下,您只需保留数据,以防用户返回此页面。@DanAbramov在尝试诸如React之类的新事物时,我通常会尝试模拟一些大的东西,比如在我的9-5工作中,这样我就可以看到如何在“现实生活”(与ToDo相反)中使用它。如果我们把一切都放在身边,从日程安排、账单、联系人管理、任务、文件等等,事情会很快失控。对于我习惯使用的应用程序类型来说,清除掉一个必要的条件——如果你好奇的话(令人困惑的是,为什么面向公众的网站没有应用程序的屏幕截图——它非常清晰)谢谢丹-根据法律,我必须再等17个小时才能获得赏金:)非常感谢你提供的信息。我战斗的日子早已过去;我很乐意离开旧的缩减器,如果实际需要的话,简单地清除多余的数据。你有没有可能找到把这些信息输入文档的方法?这几乎是redux中唯一一个文档有点有限的部分。@Adam我现在根本没有时间为文档做贡献。需要一个全面的“动态代码加载”方法,但有人需要拥有它,而我不能。不用担心。您为开发人员社区做了很多工作。在我花更多的时间在replaceReducer上更新一些文档,以便更好地理解事情之后,你会接受一份带有更新文档的PR吗?@Adam是的,但我们尽量保持API文档简洁。配方应该是更正确的形式。