React使用函数式更新器时State不更新问题求助
解决思路
1. 别直接赋值component.removed,用编辑器官方的移除事件
大概率你用的编辑器(比如GrapesJS)有自己的事件机制,直接覆盖component.removed属性根本不会被编辑器识别,自然触发不了你的回调。换成编辑器提供的component:remove事件监听才是正确姿势:
useEffect(() => { // 处理组件添加 const handleAdd = (component) => { const newComp = { settings: {}, gjsComponent: component }; setLiveComponents(prev => ({ ...prev, [component.getId()]: newComp })); }; // 处理组件移除 const handleRemove = (component) => { setLiveComponents(prev => { // 解构赋值直接剔除目标键,生成新对象 const { [component.getId()]: _, ...updated } = prev; return updated; }); }; // 绑定事件 editor.on("component:add", handleAdd); editor.on("component:remove", handleRemove); // 组件卸载时解绑,避免内存泄漏和重复触发 return () => { editor.off("component:add", handleAdd); editor.off("component:remove", handleRemove); }; }, [setLiveComponents]);
2. 把事件绑定放进useEffect,别直接写在组件里
原代码里editor.on直接写在App函数体内,每次组件渲染都会重复绑定事件,导致同一个操作触发N次回调,状态肯定乱套。用useEffect包裹后,只会在依赖变化时绑定一次,还能通过清理函数解绑,避免各种奇怪问题。
3. 确认组件ID的一致性
在添加和移除时分别打印component.getId()的值,确保两次拿到的是同一个ID——万一编辑器组件在生命周期里ID变了,或者你搞错了取ID的方式,状态更新自然找不到对应的键。
4. 排查是否有其他逻辑覆盖状态
检查项目里其他地方有没有调用setLiveComponents,比如其他事件、定时器或者父组件传递的状态更新函数,说不定你的移除操作刚更新完状态,就被其他逻辑覆盖回去了。可以在setLiveComponents的回调里加console.log,看看每次更新前后的状态变化。
内容的提问来源于stack exchange,提问作者RJZ
相关产品推荐
相关产品推荐

