让我说我有一个 rootreducer ,如下所示。
const rootR = combineReducers({
topics,
...
});
主题 reducer
function topics(state = { topics=[], error: null}, action){
switch (action.type){
case types.FETCH_TOPICS_SUCCESSFULLY:
const { topics } = action;
return {
...state,
topics,
};
default:
return state;
}
};
当我触发相关操作时,我的状态为可重复属性state.topics.topics
而不是state.topics
有没有办法避免这种重复(topics.topics
)?
提前致谢
答案 0 :(得分:1)
你是双重嵌套的东西。 topics
缩减器只会看到"主题"一片状态。因此,不要返回{...state, topics}
,而只需执行return topics
。
<强>更新强>
您对该问题的编辑会大大改变这种情况。
最初,你有:
function topics(state = {}, action){
现在,你有:
function topics(state = { topics=[], error: null}, action){
我承认,此时我对你所希望的州结构究竟应该是什么感到困惑。
看看你的原始定义,似乎你误解了combineReducers
的工作原理,并且冗余地尝试返回一个包含名为&#34; topic&#34;的字段/切片的新对象。现在,它看起来像根级&#34;主题&#34; slice本身有一个名为&#34;的主题&#34;同样。
topics
和error
应该位于州树的 root 吗?或者,他们是否真的应该成为顶级&#34;主题的一部分&#34;切片?如果这真的是你想要的,那么你已经将状态树定义为需要topics.topics
。
另外,回答@ free-soul:不,在原始示例中,return topics
不变异状态,因为它只是返回动作中的任何内容。即使action.topic
字段实际上与以前在该状态中的数组相同,结果也只是一个无操作。
答案 1 :(得分:1)
@markerikson是正确的,一旦state
被调用,函数中传递的topics
变量实际上是FETCH_TOPICS_SUCCESSFULLY
,因此最好在那里进行return topics
。
但是根据您的条件,您还可以返回{...state, topics}
而不是返回return topics
或Object.assign({}, state, topics)
。这将创建一个新对象,其中包含以前状态和主题合并在一起的所有属性。
答案 2 :(得分:1)
查看topics
reducer的initialState,topics
reducer可访问的状态对象具有以下结构:
{
topics: [],
error: null
}
所以当你combineReducers
这样时:
const rootR = combineReducers({
topics,
anotherReducer,
someOtherReducer.
// ...
});
结果全局应用状态将如下所示:
{
topics: {
topics: [],
error: null
},
anotherReducer: {
// ...
},
someOtherReducer: {
// ...
},
// ...
}
因此,如果您想从全局状态访问topics
数组,则需要执行state.topics.topics
。
state.topics
下有两件事,topics
和error
数组。
因此,我们将第二个topics
键重命名为items
以避免混淆。
(不可避免地要有第二个键来存储数组,因为你也需要error
)
因此我们有:
state.topics = {
items: [],
error: null,
}
现在我们访问state.topics.topics
state.topics.items
要实现这一点,传递给topics
reducer的initialstate必须是:
function topics(state = { items = [], error: null }, action){
//...
}
现在在reducer FETCH_TOPICS_SUCCESSFULLY
中,我们希望将数组action.topics
追加到items
,就像这样(不改变我们当前的状态):
case types.FETCH_TOPICS_SUCCESSFULLY:
const { topics } = action;
return {
...state,
items: [
...state.items,
...topics
],
};