在 React Redux 应用程序中规范化状态的示例是什么?

What is an example of normalizing the state in a React Redux app?

我正在阅读 Redux Reducers docs 并且不了解规范化状态的工作原理。示例中的当前状态是这样的:

{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}

您能否提供一个示例,说明如果我们遵循以下内容,上面的内容会是什么样子?

For example, keeping todosById: { id -> todo } and todos: array inside the state would be a better idea in a real app, but we’re keeping the example simple.

您可以为此使用 normalizr

Normalizr 采用 JSON 和一个模式,并用它们的 ID 替换嵌套实体,将所有实体收集到字典中。

例如,

[{
  id: 1,
  title: 'Some Article',
  author: {
    id: 1,
    name: 'Dan'
  }
}, {
  id: 2,
  title: 'Other Article',
  author: {
    id: 1,
    name: 'Dan'
  }
}]

可以标准化为

{
  result: [1, 2],
  entities: {
    articles: {
      1: {
        id: 1,
        title: 'Some Article',
        author: 1
      },
      2: {
        id: 2,
        title: 'Other Article',
        author: 1
      }
    },
    users: {
      1: {
        id: 1,
        name: 'Dan'
      }
    }
  }
}

此示例直接来自 Normalizr

[{
  id: 1,
  title: 'Some Article',
  author: {
    id: 1,
    name: 'Dan'
  }
}, {
  id: 2,
  title: 'Other Article',
  author: {
    id: 1,
    name: 'Dan'
  }
}]

可以这样归一化-

{
  result: [1, 2],
  entities: {
    articles: {
      1: {
        id: 1,
        title: 'Some Article',
        author: 1
      },
      2: {
        id: 2,
        title: 'Other Article',
        author: 1
      }
    },
    users: {
      1: {
        id: 1,
        name: 'Dan'
      }
    }
  }
}

归一化有什么好处?

您可以提取您想要的状态树的确切部分。

例如-您有一个对象数组,其中包含有关文章的信息。如果您想 select 该数组中的特定对象,则必须遍历整个数组。最坏的情况是数组中不存在所需的对象。为了克服这个问题,我们将数据标准化。

要规范化数据,请将每个对象的唯一标识符存储在单独的数组中。我们将该数组称为 results.

result: [1, 2, 3 ..]

并将对象数组转换为具有键的对象作为 id(请参阅第二个代码段)。将该对象称为 entities.

最终,要使用 id 1 访问对象,只需执行此操作 - entities.articles["1"]