React与Redux中规范化状态下ID引用映射的高效实现方案
Redux规范化状态结构的映射实现问题
我刚开始学习Redux,已经按照官方文档《Normalizing State Shape》章节的核心规范——任何对单个项的引用都应通过存储项的ID来实现——构建了状态结构,示例如下:
{ "taskGroups": { "byId": { "taskGroup1": { "taskGroupId": "taskGroup1", "tasks": ["task1", "task2"] // etc etc }, "taskGroup2": { "taskGroupId": "taskGroup2", "tasks": ["task2", "task3"] // etc etc } // etc etc }, "allIds": ["taskGroup1", "taskGroup2", "taskGroup3"] }, "tasks": { "byId": { "task1": { "taskId": "task1", "description": "......", "comments": ["comment1", "comment2"] // etc etc }, "task2": { "taskId": "task2", "description": "......", "comments": ["comment3", "comment4", "comment5"] // etc etc } // etc etc }, "allIds": ["task1", "task2", "task3", "task4"] }, "comments": { "byId": { "comment1": { "id": "comment1", "comment": "....." // etc etc }, "comment2": { "id": "comment2", "comment": "....." // etc etc } // etc etc }, "allIds": ["comment1", "comment2", "comment3", "comment4", "comment5"] } }
我理解这种结构的理论优势,但实践中遇到两个核心问题:
- 不确定ID数组的映射逻辑应该放在哪里:是在父组件中完成映射后传递给子组件,还是把ID引用传到子组件里再处理?
- 之前用useContext配合规范化状态时,我写了一个筛选函数来匹配taskGroup对应的任务:
export const filterObject = (objToFilter: any, valuesToFind: string[]) => { return Object.keys(objToFilter) .filter((key) => valuesToFind.includes(key)) .reduce((obj, key) => { return { ...obj, [key]: objToFilter[key], }; }, {}); };
然后在组件中这样使用(Tasks组件里也用相同逻辑映射评论):
{ Object.values(taskGroupsById) .sort((a, b) => a.sortOrder - b.sortOrder) .map((taskGroup) => { return ( <TaskGroup key={taskGroup.taskGroupId} taskGroupTitle={taskGroup.taskGroupTitle} tasks={filterObject( tasksById, taskGroup.tasks )} handleDrawer={handleDrawer} findTaskStatus={findTaskStatus} findAssignedToTask={findAssignedToTask} /> ); }); }
这个方法能正常运行,但每个TaskGroup实例都会重复执行筛选逻辑,存在重复计算的问题。我尝试在Redux切片里创建Selector,但不知道怎么处理多ID数组的映射(只会处理单个字符串引用),希望得到更优的实现方案。
内容的提问来源于stack exchange,提问作者singlservinjack
相关产品推荐
相关产品推荐

