嵌套数据规范化 createEntityAdapter
Nested Data Normalization createEntityAdapter
我正在尝试规范化具有以下结构的数据数组 Array<Application>
。使用 createEntityAdapter
.
在使用 createAsyncThunk
获取数据并返回它们之后,我确实将它们设置在 extraReducers
中,如下所示:
applicationsAdapter.setAll(state, action.payload)
在 Redux DevTools 中,我可以看到数据如下所示:
{
applications: {
ids: [
'60a684fb90957536f185ea88',
],
entities: {
'60a684fb90957536f185ea88': {
id: '60a684fb90957536f185ea88',
title: 'Article1',
description: 'The best article ever',
groups: [
{
id: 'bPDGd8uOkmKKAO3FyoTKE',
title: 'Group 1',
voters: [
{
user: {
uid: '344bc9b8-671b-4de5-ab2d-a619ea34d0ba',
username: 'tran',
},
vote: 'DECLINED'
}
]
}
],
deadline: "2021-05-20",
budget: 0,
createdAt: '2021-05-20',
createdBy: {
uid: 'ab2a8f19-c851-4a5f-9438-1000bfde205a',
username: 'admin',
},
},
}
问题:
数据未完全标准化。如何规范化组、投票者和用户对象?
接口如下:
export interface Application {
id: string;
title: string;
description: string;
groups: Array<GroupElement>;
deadline: string;
budget?: number;
createdAt: string;
createdBy: User;
}
export interface GroupElement {
id: string;
title: string;
voters: Array<Voter>;
}
export interface User {
uid: string;
username: string;
}
export interface Voter {
user: User;
vote: Decision;
}
createEntityAdapter
不会自行执行任何类型的关系规范化。您需要为此使用 normalizr
。
由于 Voter
对象缺少自己的 id 属性,因此很难规范化。我不得不拼凑一个。
import { schema, normalize } from "normalizr";
const user = new schema.Entity("user", {}, { idAttribute: "uid" });
const voter = new schema.Entity(
"voter",
{
user: user
},
{
idAttribute: (object) => `${object.vote}-${object.user.uid}`
}
);
const group = new schema.Entity("group", {
voters: [voter]
});
const application = new schema.Entity("application", {
createdBy: user,
groups: [group]
});
normalize(entity, application);
这会将您的数据转换为:
{
"entities": {
"user": {
"ab2a8f19-c851-4a5f-9438-1000bfde205a": {
"uid": "ab2a8f19-c851-4a5f-9438-1000bfde205a",
"username": "admin"
},
"344bc9b8-671b-4de5-ab2d-a619ea34d0ba": {
"uid": "344bc9b8-671b-4de5-ab2d-a619ea34d0ba",
"username": "tran"
}
},
"voter": {
"DECLINED-344bc9b8-671b-4de5-ab2d-a619ea34d0ba": {
"user": "344bc9b8-671b-4de5-ab2d-a619ea34d0ba",
"vote": "DECLINED"
}
},
"group": {
"bPDGd8uOkmKKAO3FyoTKE": {
"id": "bPDGd8uOkmKKAO3FyoTKE",
"title": "Group 1",
"voters": ["DECLINED-344bc9b8-671b-4de5-ab2d-a619ea34d0ba"]
}
},
"application": {
"60a684fb90957536f185ea88": {
"id": "60a684fb90957536f185ea88",
"title": "Article1",
"description": "The best article ever",
"groups": ["bPDGd8uOkmKKAO3FyoTKE"],
"deadline": "2021-05-20",
"budget": 0,
"createdAt": "2021-05-20",
"createdBy": "ab2a8f19-c851-4a5f-9438-1000bfde205a"
}
}
},
"result": "60a684fb90957536f185ea88"
}
我同意你的看法。 createEntityAdapter 似乎进行第一层规范化,因此输出“ids / entities”。我不确定将它与 normalizr 一起使用是可行的方法,因为 createEntityAdapter 的 API 公开了一些将数据放回其中的方法,例如 addONe 或 addMany,如果您将它与 normalizr 一起使用以规范化嵌套数据,我不会不认为您可以使用最外层的方法,例如 addOne 或 Addmany 用于您使用库 (normalizr) 规范化的嵌套方法。
我正在尝试规范化具有以下结构的数据数组 Array<Application>
。使用 createEntityAdapter
.
在使用 createAsyncThunk
获取数据并返回它们之后,我确实将它们设置在 extraReducers
中,如下所示:
applicationsAdapter.setAll(state, action.payload)
在 Redux DevTools 中,我可以看到数据如下所示:
{
applications: {
ids: [
'60a684fb90957536f185ea88',
],
entities: {
'60a684fb90957536f185ea88': {
id: '60a684fb90957536f185ea88',
title: 'Article1',
description: 'The best article ever',
groups: [
{
id: 'bPDGd8uOkmKKAO3FyoTKE',
title: 'Group 1',
voters: [
{
user: {
uid: '344bc9b8-671b-4de5-ab2d-a619ea34d0ba',
username: 'tran',
},
vote: 'DECLINED'
}
]
}
],
deadline: "2021-05-20",
budget: 0,
createdAt: '2021-05-20',
createdBy: {
uid: 'ab2a8f19-c851-4a5f-9438-1000bfde205a',
username: 'admin',
},
},
}
问题: 数据未完全标准化。如何规范化组、投票者和用户对象?
接口如下:
export interface Application {
id: string;
title: string;
description: string;
groups: Array<GroupElement>;
deadline: string;
budget?: number;
createdAt: string;
createdBy: User;
}
export interface GroupElement {
id: string;
title: string;
voters: Array<Voter>;
}
export interface User {
uid: string;
username: string;
}
export interface Voter {
user: User;
vote: Decision;
}
createEntityAdapter
不会自行执行任何类型的关系规范化。您需要为此使用 normalizr
。
由于 Voter
对象缺少自己的 id 属性,因此很难规范化。我不得不拼凑一个。
import { schema, normalize } from "normalizr";
const user = new schema.Entity("user", {}, { idAttribute: "uid" });
const voter = new schema.Entity(
"voter",
{
user: user
},
{
idAttribute: (object) => `${object.vote}-${object.user.uid}`
}
);
const group = new schema.Entity("group", {
voters: [voter]
});
const application = new schema.Entity("application", {
createdBy: user,
groups: [group]
});
normalize(entity, application);
这会将您的数据转换为:
{
"entities": {
"user": {
"ab2a8f19-c851-4a5f-9438-1000bfde205a": {
"uid": "ab2a8f19-c851-4a5f-9438-1000bfde205a",
"username": "admin"
},
"344bc9b8-671b-4de5-ab2d-a619ea34d0ba": {
"uid": "344bc9b8-671b-4de5-ab2d-a619ea34d0ba",
"username": "tran"
}
},
"voter": {
"DECLINED-344bc9b8-671b-4de5-ab2d-a619ea34d0ba": {
"user": "344bc9b8-671b-4de5-ab2d-a619ea34d0ba",
"vote": "DECLINED"
}
},
"group": {
"bPDGd8uOkmKKAO3FyoTKE": {
"id": "bPDGd8uOkmKKAO3FyoTKE",
"title": "Group 1",
"voters": ["DECLINED-344bc9b8-671b-4de5-ab2d-a619ea34d0ba"]
}
},
"application": {
"60a684fb90957536f185ea88": {
"id": "60a684fb90957536f185ea88",
"title": "Article1",
"description": "The best article ever",
"groups": ["bPDGd8uOkmKKAO3FyoTKE"],
"deadline": "2021-05-20",
"budget": 0,
"createdAt": "2021-05-20",
"createdBy": "ab2a8f19-c851-4a5f-9438-1000bfde205a"
}
}
},
"result": "60a684fb90957536f185ea88"
}
我同意你的看法。 createEntityAdapter 似乎进行第一层规范化,因此输出“ids / entities”。我不确定将它与 normalizr 一起使用是可行的方法,因为 createEntityAdapter 的 API 公开了一些将数据放回其中的方法,例如 addONe 或 addMany,如果您将它与 normalizr 一起使用以规范化嵌套数据,我不会不认为您可以使用最外层的方法,例如 addOne 或 Addmany 用于您使用库 (normalizr) 规范化的嵌套方法。