Redux将状态树规范化为帖子和评论

时间:2016-07-19 08:59:43

标签: mongodb redux

Redux建议使用规范化的应用程序状态树,但我不确定这是否是这种情况下的最佳做法。假设以下情况:

  1. 每个Circle has_many Posts
  2. 每个Post has_many Comments
  3. 在后端的数据库中,每个模型如下所示:

    界:

    {
      _id: '1'
      title: 'BoyBand'
    }
    

    发表:

    {
      _id: '1',
      circle_id: '1',
      body: "Some Post"
    }
    

    注释:

    {
      _id: '1',
      post_id: '1',
      body: "Some Comment"
    }
    

    在前端的应用状态(所有缩减器的最终结果)如下所示:

    {
      circles: {
        byId: {
          1: {
            title: 'BoyBand'
          }
        },
        allIds: [1]
      },
      posts: {
        byId: {
          1: {
            circle_id: '1',
            body: 'Some Post'
          }
        },
        allIds: [1]
      },
      comments: {
        byId: {
          1: {
            post_id: '1',
            body: 'Some Comment'
          },
        allIds: [1]
      }
    }
    

    现在,当我转到CircleView时,我会从后端获取Circle,后端会返回与之关联的所有postscomments

    export const fetchCircle = (title) => (dispatch, getState) => {
      dispatch({
        type: constants.REQUEST_CIRCLE,
        data: { title: title }
      })
    
      request
        .get(`${API_URL}/circles/${title}`)
        .end((err, res) => {
          if (err) {
            return
          }
    
          // When you fetch circle from the API, the API returns:
          // {
          //   circle: circleObj,
          //   posts: postsArr,
          //   comments: commentsArr
          // }
          // so it's easier for the reducers to consume the data
    
          dispatch({
            type: constants.RECEIVE_CIRCLE,
            data: (normalize(res.body.circle, schema.circle))
          })
          dispatch({
            type: 'RECEIVE_POSTS',
            data: (normalize(res.body.posts, schema.arrayOfPosts))
          })
          dispatch({
            type: 'RECEIVE_COMMENTS',
            data: (normalize(res.body.comments, schema.arrayOfComments))
          })
        })
    }
    

    到目前为止,我认为我以相当标准的方式做了一切。但是,当我想渲染每个Post组件时,我意识到用我们的注释填充帖子变得效率低下(O(N ^ 2))与我以下列格式保存状态树相比。

    {
      circles: {
        byId: {
          1: {
            title: 'BoyBand'
          }
        },
        allIds: [1]
      },
      posts: {
        byId: {
          1: {
            circle_id: '1',
            body: 'Some Post'
            comments: [arrOfComments]
          }
        },
        allIds: [1]
      }
    }
    

    这违背了我的理解,在redux状态树中,最好保持所有规范化。

    问。我是否应该在这种情况下保持非规范化的事情?我如何确定该怎么做?

2 个答案:

答案 0 :(得分:2)

我想去:是的,将它标准化,但是在后端进行!

<强>为什么吗

  • 删除更容易

因为否则,每次您想要删除圈子或发帖时,您都必须追踪帖子和评论。

  • 使用数据更容易

因为否则,您必须反复对数据进行相同的突变,以便您可以选择与特定圈子或帖子相关的数据集。

  • 您没有任何多对多的关系

您没有多个帖子链接到相同的评论,因此将数据标准化是有意义的。

  • 您不应受API限制

如果这是第三方API,那么请让后端获取API并将数据规范化。您不应该受到API的限制,我也不知道您访问了哪种数据,但如果API不可用,您可以明确地为用户保存DNS查找并提供缓存数据。如果您依赖API,那么就会引入单点故障。

关于您的性能问题,如果您在后端进行规范化,那么它们应该是无关紧要的,您应该对其进行测量并采用关键代码进行代码审查。

答案 1 :(得分:0)

在我看来,评论列表是针对任何帖子的。用户无法在多个帖子中发布一条评论。评论与帖子紧密结合并没有错。更新/删除特定注释很容易(postId和commentId都存在)。删除帖子很简单。与圆相同。删除特定用户的所有评论显然更加困难。我认为没有严格的规则,正确的方式等......更多的是它取决于。 KiSS;)

在思考如何在客户端组织评论时,我正在阅读本文,它是关于类似情况的可能的数据库结构。 https://docs.mongodb.com/ecosystem/use-cases/storing-comments/