避免重复的州名

时间:2016-11-28 19:09:35

标签: javascript reactjs ecmascript-6 redux

让我说我有一个 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)?

提前致谢

3 个答案:

答案 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;同样。

topicserror应该位于州树的 root 吗?或者,他们是否真的应该成为顶级&#34;主题的一部分&#34;切片?如果这真的是你想要的,那么你已经将状态树定义为需要topics.topics

另外,回答@ free-soul:不,在原始示例中,return topics 变异状态,因为它只是返回动作中的任何内容。即使action.topic字段实际上与以前在该状态中的数组相同,结果也只是一个无操作。

答案 1 :(得分:1)

@markerikson是正确的,一旦state被调用,函数中传递的topics变量实际上是FETCH_TOPICS_SUCCESSFULLY,因此最好在那里进行return topics。 但是根据您的条件,您还可以返回{...state, topics}而不是返回return topicsObject.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下有两件事,topicserror数组。 因此,我们将第二个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
        ],
    };