我有一个关于在Redux Toolkit中使用createEntityAdapter的问题。
我有一个应用程序,它使用AG Grid库的master/detail功能显示包和包的详细信息。应用程序首先加载包数据,然后在每个包行展开时获取详细数据。
我想使用createEntityAdapter以一种标准化的方式管理数据,但我在弄清楚如何处理细节网格的动态特性时遇到了麻烦。现在,我有一个reducer切片,它在每次加载一组详细记录时创建一个新属性。属性键是父程序包行的id,因此在加载程序包数据和123详细信息数据后,我的data切片最终如下所示:
{
PACKAGES: [{ id: 123, ...otherData }, { id: 124, ...otherData }],
'123': [{ id: 456, ...otherDetailData }],
}当用户展开124包行时,将获取该包的详细数据,然后如下所示:
{
PACKAGES: [{ id: 123, ...otherData }, { id: 124, ...otherData }],
'123': [{ id: 456, ...otherDetailData }],
'124': [{ id: 457, ...otherDetailData }],
}因此,虽然我可以将PACKAGES数据分解到它自己的实体适配器中,但我不能对细节网格做同样的事情,因为我事先不知道每个细节网格。
我想我和来自this issue的那个人有类似的问题。
我考虑过将所有细节数据存储在单个实体适配器中,并通过父id维护另一个索引,但这似乎很难保持同步。
有什么想法吗?此场景中的最佳实践是什么?
发布于 2021-03-02 00:37:47
我创建并维护了Redux Toolkit,实际上我最近确实用嵌套的实体适配器做了一些类似的事情。
在我的例子中,当父项被添加或删除时,我需要维护这些辅助数据集。
interface ChildrenEntry {
parentId: ParentId;
children: EntityState<ChildType>
}
interface ChildrenData {
parentId: ParentId;
children: ChildType[];
}
interface NewChildAdded {
parentId: ParentId;
child: ChildType;
}
export const childEntriesAdapter = createEntityAdapter<ChildrenEntry>();
export const childrenAdapter = createEntityAdapter<ChildType>();
const initialState = childEntriesAdapter.getInitialState();
const createNewChildEntry = (parentId: ParentId) => ({
parentId,
children: childrenAdapter.getInitialState()
});
const childEntriesSlice = createSlice({
name: "children",
initialState,
reducers: {
childEntriesLoaded(state, action: PayloadAction<ChildrenData>) {
const {parentId, children} = action.payload;
const childEntry = state.entities[parentId];
if (childEntry) {
childrenAdapter.setAll(childEntry.children, children);
}
},
// etc
},
extraReducers: builder => {
builder
.addCase(parentLoaded, (state, action) => {
const childEntries = action.payload.map(parent => createNewChildEntry(parent.id));
childEntriesAdapter.setAll(state, childEntries);
})
.addCase(parentDeleted, (state, action) => {
childEntriesAdapter.removeOne(state, action);
})
.addCase(parentAdded, (state, action) => {
const childEntry = createNewChildEntry(action.payload.id);
childEntriesAdapter.addOne(state, childEntry);
});
}
})也许有更好的方法来处理这件事,但它对我的需求来说已经足够好了。
https://stackoverflow.com/questions/66412450
复制相似问题