React中使用State Hooks动态创建对象的对象的实现问题
解决React中按分组构建嵌套对象State的问题
问题分析
你的代码核心问题是更新分组时,直接替换了整个分组的对象,没有保留该分组下已有的管道数据。React的useState更新需要遵循不可变更新原则,必须基于前一个状态构建新对象,不能直接修改原状态。
修正方案
修改updatePipelineGroupObjects函数,在更新指定分组时,先保留该分组已有的管道,再合并新的管道(同名管道会自动覆盖):
const [groupedPipelineObjects, setGroupedPipelineObjects] = useState({}); const [socketState, ready, message, send] = useContext(WebsocketContext); useEffect(() => { if (message) { updatePipelineGroupObjects(message); } }, [message]); const updatePipelineGroupObjects = (data) => { const pipelineName = data.name; const pipelineGroup = data.group; setGroupedPipelineObjects(prevState => ({ // 保留所有已有分组 ...prevState, // 更新目标分组:如果分组已存在,展开原有管道再添加新管道;否则创建新分组 [pipelineGroup]: { ...prevState[pipelineGroup], // 保留该分组下已有的管道 [pipelineName]: data // 添加/覆盖当前管道 } })); };
关键说明
- 不可变更新:通过展开运算符
...复制前一个状态的所有属性,确保原state不被直接修改,符合React的状态更新规则。 - 分组合并逻辑:
...prevState[pipelineGroup]会自动处理两种情况:- 如果该分组已存在,就保留里面的所有管道对象;
- 如果分组不存在,
prevState[pipelineGroup]是undefined,展开后相当于空对象,不会影响新分组的创建。
- 管道覆盖规则:因为管道名称唯一,新的
[pipelineName]: data会自动覆盖分组中同名的管道数据,满足你的需求。
验证效果
假设依次收到你给出的三条数据,最终groupedPipelineObjects会生成如下结构:
{ "Group1": { "PipelineA": {"name": "PipelineA", "state": "succeeded", "group": "Group1"}, "PipelineE": {"name": "PipelineE", "state": "succeeded", "group": "Group1"} }, "Group4": { "PipelineZ": {"name": "PipelineZ", "state": "succeeded", "group": "Group4"} } }
内容的提问来源于stack exchange,提问作者iSaWcH
相关产品推荐
相关产品推荐

