非规范化数据如何导致 React Redux 出现问题?

How can non-normalized data cause problems in react redux?

查看来自 redux 的 reddit 文档 example,Dan 说:

{
  selectedSubreddit: 'frontend',
  postsBySubreddit: {
    frontend: {
      isFetching: true,
      didInvalidate: false,
      items: []
    },
    reactjs: {
      isFetching: false,
      didInvalidate: false,
      lastUpdated: 1439478405547,
      items: [
        {
          id: 42,
          title: 'Confusion about Flux and Relay'
        },
        {
          id: 500,
          title: 'Creating a Simple Application Using React JS and Flux Architecture'
        }
      ]
    }
  }
}

In this example, we store the received items together with the pagination information. However, this approach won’t work well if you have nested entities referencing each other, or if you let the user edit items. Imagine the user wants to edit a fetched post, but this post is duplicated in several places in the state tree. This would be really painful to implement.

谁能解释一下他指的分页信息是什么?另外,如果用户想要编辑获取的 post 会是什么样子?这如何导致 post 在状态树的多个位置被复制?

我相信lastUpdated 属性是他指的分页数据;它可用于(取决于 API)提取自上次更新以来所做的更改。

您对规范化的困惑是可以理解的,因为他没有包含 non-normalized 方法不好的案例示例 - 尽管在文档的下一段中,他确实提供了一个示例规范化结构在需要它的情况下会是什么样子。

但请考虑这种情况:我们仍在管理一个跟踪 'posts' 的数据集,这些 'posts' 是 'subreddits' 的一部分。但是现在我们允许单个 post 是 'cross-posted' 的可能性,并且我们将其表示为每个子版块 object 中包含的相同单个 post,其中这是 cross-posted.

假设 post 42 是 cross-posted。现在 non-normalized 状态如下所示:

{
  selectedSubreddit: 'frontend',
  postsBySubreddit: {
    frontend: {
      isFetching: true,
      didInvalidate: false,
      items: [            {
          id: 42,
          title: 'Confusion about Flux and Relay'
        }
      ]
    },
    reactjs: {
      isFetching: false,
      didInvalidate: false,
      lastUpdated: 1439478405547,
      items: [
        {
          id: 42,
          title: 'Confusion about Flux and Relay'
        },
        {
          id: 500,
          title: 'Creating a Simple Application Using React JS and Flux Architecture'
        }
      ]
    }
  }
}

现在用户正在查看 subreddit 'reactjs' 并想编辑 post 42 的标题。我们还应该更新 subreddit [=32] 下的 SAME post 的标题=],但如果不全面搜索我们的状态,我们无法知道这一点。因此,我们要么进行代价高昂的搜索,要么引入数据完整性问题。

规范化后,此状态类似于:

{
  selectedSubreddit: 'frontend',
  posts: {
    42: {
      id: 42,
      title: 'Confusion about Flux and Relay'
    },
    500: {
      id: 500,
      title: 'Creating a Simple Application Using React JS and Flux Architecture'
    }
  },
  postsBySubreddit: {
    frontend: {
      isFetching: true,
      didInvalidate: false,
      items: [42]
    },
    reactjs: {
      isFetching: false,
      didInvalidate: false,
      lastUpdated: 1439478405547,
      items: [42,500]
    }
  }
}

这样存储,post 42 的详细信息只存在一个地方,因此可以在一个地方编辑它们并应用于可能存在的每个引用。

当然,也可以使用 object 引用来完成此操作,将相同的 object 放入两个子版块的数组中。然而,这与 Redux 并不是特别兼容,在 Redux 中状态改变 return 新的 object 而不是改变现有的。使用规范化引用可以很好地处理不可变数据,这对 Redux state 来说是一个优势。