注入 asyncReducers 时的 preloadedState

Posted

技术标签:

【中文标题】注入 asyncReducers 时的 preloadedState【英文标题】:preloadedState when injecting asyncReducers 【发布时间】:2019-05-13 08:04:09 【问题描述】:

如何同时拥有 preloadedState(从服务器补水)和动态注入 reducer?

react-boilerplate 或How to dynamically load reducers for code splitting in a Redux application? 中存在基于您正在查看的页面/组件动态添加的reducer 的概念。摘自reducers.js

export default function createReducer(asyncReducers) 
  return combineReducers(
    users,
    posts,
    ...asyncReducers
  );

虽然这在从一个页面导航到另一个页面(或仅在客户端应用程序上)时效果很好;当从服务器补水数据时,我遇到了这个错误:

Unexpected property "comments" found in previous state received by the reducer. Expected to find one of the known reducer property names instead: "users", "posts". Unexpected properties will be ignored.

(其中comments是动态注入reducer的属性名)

这个错误的原因很清楚,因为来自服务器的preloadedState(使用React s-s-r)已经包含comments,而初始reducer没有,因为这是之后动态添加的。如果我将comments 添加到我的combineReducers,错误就会消失;但这意味着在应用程序初始化时,我需要包含所有减速器;这并不理想。

【问题讨论】:

【参考方案1】:

您应该能够使用虚拟减速器代替动态加载的减速器,动态加载的减速器将在加载真正的减速器时被替换。

 comments: (state = null) => state 

这也可以自动完成,具体取决于您的实现,根据 http://nicolasgallagher.com/redux-modules-and-code-splitting/

// Preserve initial state for not-yet-loaded reducers
const combine = (reducers) => 
  const reducerNames = Object.keys(reducers);
  Object.keys(initialState).forEach(item => 
    if (reducerNames.indexOf(item) === -1) 
      reducers[item] = (state = null) => state;
    
  );
  return combineReducers(reducers);
;

【讨论】:

以上是关于注入 asyncReducers 时的 preloadedState的主要内容,如果未能解决你的问题,请参考以下文章

扩展类时的构造函数注入

sql手工注入时的探测技巧汇总

将依赖项注入ViewModel时的Dagger / MissingBinding

在 asp.net Core 中配置服务注册时的依赖注入访问 (3+)

Sonar 和 findsecbugs 使用 Spring Expression 时的潜在代码注入

将 MVC 视图呈现为 Parallel.ForEach 中的字符串时的依赖注入问题