小编典典

ReplaceReducer导致意外的键错误

reactjs

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

在initialState参数中找到意外的键“ bookEntry”传递给createStore。期望找到已知的化简键之一:“ bookList”,“
root”。意外的键将被忽略。

其中bookEntry 要更换的旧减速机的关键。从bookEntry模块开始并切换到bookList会导致此反向错误

在initialState参数中找到意外的键“ bookList”传递给createStore。期望找到已知的化简键之一:“ 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
    }));
}

阅读 403

收藏
2020-07-22

共1个答案

小编典典

通常, 我们 建议您在更改路线或加载新模块时“清理”数据。这使应用程序难以预测。如果我们在谈论 数十万
条记录,那么可以肯定。这是您计划加载的数据量吗?

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

现在,到警告消息。该检查定义在内部combineReducers()。这意味着意外状态键将被丢弃。删除了bookEntry托管的reducer后,state.bookEntry新的root
reducer不再识别该状态的一部分,并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));
}

但是,我们建议的模式是保持旧的减速器

2020-07-22