Inject reducer arbitrarily rather than top level for redux store to replace reducer

简介: When writing a big react redux application or any SPA using redux, there is a need to split code with webpack and load reducers asynchronously. The way to load reducer asynchronously is utilizing red

When writing a big react redux application or any SPA using redux, there is a need to split code with webpack and load reducers asynchronously.

The way to load reducer asynchronously is utilizing redux store replaceReducer. There is typical sample of inject reducer like injectReducerfunction in https://github.com/davezuko/react-redux-starter-kit/blob/master/src/store/reducers.js. It only can replace the top level reducer in asyncReducers . For example.

asyncReducers = {
products: combineReducers({
list: productListReducer,
one: productReducer
}),
orders: ordersReducer
}

The injectReducer function only can replace products or orders which is top level in asyncReducers.

But there might be many chance that only asynchronously inject reducer with top one not enough since the split javascript file is still big.

Here introduce a way to inject reducer in arbitrary nested level.

The injectReducer function api change a little bit, the key is in the form of products or products.list and reducer is pure reducer not one by combineReducers . Then we can use key which is . separated to build nested object of asyncReducers which is kind of tree structure and leaf value is the pure reducer. With this information, it is easy to use combineReducers to rebuild the root reducer which is used by redux store replaceReducerfunction.

const replaceAsyncReducers = (rootReducers, keys, reducer) => {
let key = keys.shift()
if (keys.length === 0) {
rootReducers[key] = reducer
return
}
if (rootReducers[key] === undefined) rootReducers[key] = {}
let nextRootReducers = rootReducers[key]
return replaceAsyncReducers(nextRootReducers, keys, reducer)
}
const combineAsyncReducers = (asyncReducers) => {
if (typeof asyncReducers !== 'object') return asyncReducers
let combineReducerObject = {}
for (let prop in asyncReducers) {
if (!asyncReducers.hasOwnProperty(prop)) continue
let value = asyncReducers[prop]
if (typeof value === 'object') {
combineReducerObject[prop] = combineAsyncReducers(value)
} else if (typeof value === 'function') {
combineReducerObject[prop] = value
}
}
return combineReducers(combineReducerObject)
}
export const makeRootReducer = (asyncReducers) => {
let newAsyncReducers = {}
console.log(asyncReducers)
for (let key in asyncReducers) {
if (!asyncReducers.hasOwnProperty(key)) continue
newAsyncReducers[key] = combineAsyncReducers(asyncReducers[key])
}
  return combineReducers({
location: locationReducer,
...asyncReducers
})
}
export const injectReducer = (store, { key, reducer }) => {
let keys = key.split('.')
replaceAsyncReducers(store.asyncReducers, keys, reducer)
// store.asyncReducers[key] = reducer
store.replaceReducer(makeRootReducer(store.apolloClient, store.asyncReducers))
}

With this change, we can inject reducer anywhere with injectReducer(store, { key: 'products.list', reducer: productListReducer }) .

目录
相关文章
|
JavaScript 前端开发
为什么import store from ‘./store‘和 ‘./store/index‘一样
为什么import store from ‘./store‘和 ‘./store/index‘一样
158 0
|
2月前
|
缓存 监控 JavaScript
computed 属性和 watch 方法的性能比较
【10月更文挑战第3天】
37 4
|
3月前
|
JavaScript 前端开发
js map和reduce
js map和reduce
|
4月前
|
存储 JavaScript 前端开发
Redux 中的 Reducer 和 Action
【8月更文挑战第31天】
66 0
|
5月前
echarts 报错 —— Component series.map not exists. Load it first
echarts 报错 —— Component series.map not exists. Load it first
155 0
|
6月前
|
前端开发 调度
react 使用 Reducer 和 Context 进行纵向扩展
react 使用 Reducer 和 Context 进行纵向扩展
|
7月前
|
存储 JavaScript
深入理解 Vuex 中的this.$store.dispatch方法
深入理解 Vuex 中的this.$store.dispatch方法
深入理解 Vuex 中的this.$store.dispatch方法
|
7月前
|
缓存 监控 JavaScript
methods、computed、watch它们的差异与区别
在Vue中,Methods、Watch和Computed是三种用于处理数据和响应数据变化的不同方式。
124 0
|
JavaScript
[Vue warn] Error in callback for immediate watcher “data“ “TypeError Cannot read property ‘reduce
[Vue warn] Error in callback for immediate watcher “data“ “TypeError Cannot read property ‘reduce
426 0
|
前端开发
react学习案例14-store,action,reducer
react学习案例14-store,action,reducer
54 0
react学习案例14-store,action,reducer