注入 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的主要内容,如果未能解决你的问题,请参考以下文章
将依赖项注入ViewModel时的Dagger / MissingBinding
在 asp.net Core 中配置服务注册时的依赖注入访问 (3+)