目标
当路线发生变化时,我想更改减速器(并为它们提供新状态)。
当前尝试
/components/:slug
我有一个由我的ComponentPage
减速器处理的 slug ( ) 设置的路线。这个 reducer 注意到路由发生了变化(通过 Redux-saga),并有机会获取与当前:slug
.
当路由器第一次更新到一个/components
页面时,状态看起来像这样:
route: {...}
language: {...}
theme: {...}
componentPage: {
content: {[default / empty]}
}
ComponentPage
获取与 相关的数据后:slug
,它看起来像这样:
route: {...}
language: {...}
theme: {...}
componentPage: {
content: {...}
liveExample: {...}
tabCollection: {...}
}
在上面的状态树中,像liveExample
和tabCollection
表示由它们自己的 reducer 管理的新域(并且它们的初始状态由 设置componentPageReducer
)。
我的意图是像这样的项目将ComponentPage
根据页面动态设置,:slug
以便可以将它们换成其他组件,而不会用可能出现在组件页面的每个可能实例上的每个可能组件乱扔状态树。
问题
我目前设置了配置文件来导入每个页面需要的特定减速器,以便它们可以ComponentPage
基于:slug
. 不幸的是,我当前的实现方法仅足以处理初始渲染——在传递之后,导入的 reducer 被它们返回的对象替换。
我目前正在处理的对象的示例ComponentPage
pageConfiguration = {
content: {...},
liveExample: (state, action) => liveExampleReducer(state || liveExampleConfiguration, action),
tabCollection: (state, action) => tabCollectionReducer(state || tabCollectionConfiguration, action),
}
关于我如何做到这一点的说明:
ReduxcombineReducers
会返回一些这样的结构:
liveExample: liveExampleReducer(liveExampleConfiguration, action),
tabCollection: tabCollectionReducer(tabCollectionConfiguration, action),
那将是理想的(如果我只知道如何将这些列为适当的减速器)。相反,我必须使函数可调用,以便我可以传入action
(当componentPageReducer
不匹配时action.type
,它仍然会尝试手动调用这些动态加载的减速器,如下所示)。(他们也接受state || configuration
这样当这些被随后调用时,他们不会继续使用配置/初始数据重新初始化)。
ComponentPage/reducer.js
export default function componentPageReducer(state = initialState, action) {
switch (action.type) {
case FETCH_SLUG:
// gets the `pageConfiguration` object from above,
// and generates the state by manually mapping through
// its functions and calling them
if (pages.has(action.payload.slug)) {
return pages.get(action.payload.slug).map((x) => {
if (typeof x === 'function') {
return x(undefined, action)
}
return x
})
}
return state
default:
// an attempt at calling the now-nonexistent
// imported reducer functions
return state.map((x) => {
if (typeof x === 'function') {
return x(state, action)
}
return x
})
}
}
可能的解决方案
所以,据我所知,如果我将 reducer 函数本身存储在 state 中并将它们的值映射到不同的键上,这样它们就不会替换自己,那么这可能会起作用,但是......看起来我正在下降奇怪的路在这里。return
我认为我目前正在拼凑一些可能不应该被认为是适当的 Reducer Composition 的东西。我不知道是否有更优雅的方式来处理这种情况。