Redux:规范全球状态

时间:2016-06-25 21:05:23

标签: reactjs redux

假设以下情况:

1. Page has many posts
2. Post has many comments

我有以下减速器:

1. PagesReducer
2. PostsReducer
3. PostReducer
4. CommentsReducer

我现在有以下状态:

pagesByTitle: {
  dorrisPage: {
    isFetching: false,
    data: {
      _id: "..."
      title: "dorrisPage",
    },
    posts: [
      {
        isFetching: false,
        data: {
          _id: "..",
          body: ".."
        },
        comments: [..]
       }
    ]
  }
}

上面的结构最初看起来还不错,但我意识到我必须传递action的子状态。例如,如果我调度了一个名为

的动作
ADD_COMMENT

我会将操作传递给PagesReducerPostsReducerPostReducerCommentsReducer,最后CommentsReducer将处理该操作。我想这是在我意识到为什么在Redux中推荐规范化状态的时候。

你能帮我解决以下问题吗?

  1. 在这种情况下,我的国家正常化动机是否正确?
  2. 规范化示例状态的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

你应该避免嵌套

来自redux docs:

  

在更复杂的应用中,您将需要不同的实体   互相参考。我们建议您保持自己的状态   尽可能标准化,没有任何嵌套。保持每个实体   以ID作为键存储的对象,并使用ID从中引用它   其他实体或列表。将应用程序的状态视为数据库。这个   方法在normalizr的文档中有详细描述。

对于标准化状态,您可以使用normalizr

pages:{
    items:{
        1:{id: 1,title: "dorrisPage", posts:[33,57]}
        2:{id: 2, title: "anotherPage",posts:[57]}
    },
    isFetching: false,
    itemIds:[1,2,..]
},
posts:{
    items:{
        33:{id: 33,title: "Post33", comments:[1,2]}
        57:{id: 57, title: "Post57", comments:[]}
    },
    isFetching: false,
    itemIds:[33,57,..]
}
comments:{
    items:{
        1:{id: 1, user: "user1", text:"fds"}
        2:{id: 2, user: "user2", text:"fds2"}
    },
    isFetching: false,
    itemIds:[1,2,..]
}

<强>&#34; itemIds&#34;物品订购是必要的

然后减速器可能看起来像这样

export const posts = (state = initialState, action) => {
    switch (action.type) {

        case type.FETCH_POSTS_REQUEST:
        case type.FETCH_POSTS_FAILURE:
            return {...state, isFetching: action.isFetching};
        case type.FETCH_POSTS_SUCCESS:
        return {...state,
            isFetching: action.isFetching,
            items: action.entities.posts, itemsIds: action.result
        };

        case type.DELETE_POST:
        return {...state,
            items: omit(state.items, action.id),
            itemsIds: state.itemsIds.filter(id=>id !== action.id)
        };
        case type.UPDATE_POST:
        return {...state, items: {...state.items,
                [action.post.id]: {...state.items[action.post.id],...action.post}}};

        default:
        return state;
    }
}

通过ID更轻松地查询帖子:

const mapStateToProps = (state,ownProps) =({
    post:state.posts.items[ownProps.id]
})

用于计算来自redux商店的派生数据,您可以使用Reselect创建已记忆的,可组合的选择器函数

video tutorial