React动态模态框关闭触发NotFoundError错误求助
解决React中Syncfusion动态Tab模态框关闭时的removeChild错误
在使用Syncfusion的TabComponent配合模态框实现学生成绩管理功能时,多次打开/关闭不同学生的模态框后,会抛出以下错误:
NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node
问题原因
该错误源于Syncfusion Tab组件在动态更新子项时,与React的DOM卸载时序不匹配:旧的Tab项DOM节点未被完全清理,新的Tab项就已挂载,导致组件尝试移除不存在的DOM节点。
解决方案
1. 关闭模态框时重置Tab状态
关闭模态框时,先清空存储Tab项的状态,避免旧的JSX元素残留引发DOM冲突:
<button className="float-right text-2xl" onClick={(e) => { e.preventDefault(); setTabDirectiveElement([]); // 重置Tab项状态 setShowPerformanceModal(false); }} > <MdOutlineCancel /> </button>
2. 给TabComponent添加唯一Key强制重渲染
每次打开不同学生的模态框时,给TabComponent设置基于当前学生标识的key,让React创建全新的Tab实例,避免复用旧组件的DOM引用:
<TabComponent heightAdjustMode="Auto" key={studentData.email} // 用学生邮箱作为唯一标识 > <TabItemsDirective>{tabDirectiveElement}</TabItemsDirective> </TabComponent>
3. 优化TabItemDirective的Key值
原代码使用index作为Tab项的key,当Tab项数量/顺序变化时易引发组件复用问题,改为用assessment的唯一标识作为key:
const tabElement = Object.keys(assessment).map((item) => { return ( <TabItemDirective key={item} // 用assessment的key替代index header={{ text: item.toLocaleUpperCase().replace('_', ' ') }} content={() => ( <TabsContentStudentManagement assessment={item} assessmentItem={[...assessment[item]]} setShowPerformanceModal={setShowPerformanceModal} criteriaOverall={criteriaOverall} studentId={studentId} classSubjectId={classSubjectId} refetchStudentClass={refetchStudentClass} setTabDirectiveElement={setTabDirectiveElement} /> )} /> ); });
4. 手动销毁Tab实例(可选)
若上述方法未完全解决问题,可在模态框关闭时手动销毁Syncfusion Tab实例,确保DOM节点被彻底清理:
import { useRef, useEffect } from 'react'; // ...组件内部 const tabRef = useRef(null); useEffect(() => { if (!showperformanceModal && tabRef.current) { tabRef.current.destroy(); // 销毁Tab实例 tabRef.current = null; } }, [showperformanceModal]); // 渲染时绑定ref <TabComponent ref={tabRef} heightAdjustMode="Auto" key={studentData.email} > <TabItemsDirective>{tabDirectiveElement}</TabItemsDirective> </TabComponent>
内容的提问来源于stack exchange,提问作者CodeEx
相关产品推荐
相关产品推荐

