最近在一个React 前端的项目上遇到需求,需要弹两个modal框,modal框上再弹modal框,这需求实在是难为情,没办法只能搞下去,弹第二个时候框没啥问题,但是第二框消失的时候,报如下错误
Error: Your focus-trap must have at least one container with at least one tabbable node in it at all times
at updateTabbableNodes2 (index.js:396:13)
at Object.unpause (index.js:1010:7)
at Object.deactivateTrap (index.js:35:39)
at Object.deactivate2 [as deactivate] (index.js:948:24)
at FocusTrap.tsx:32:17
at safelyCallDestroy (react-dom.development.js:22932:5)
at commitHookEffectListUnmount (react-dom.development.js:23100:11)
at commitPassiveUnmountInsideDeletedTreeOnFiber (react-dom.development.js:25101:11)
at commitPassiveUnmountEffectsInsideOfDeletedTree_begin (react-dom.development.js:25048:5)
at commitPassiveUnmountEffects_begin (react-dom.development.js:24956:11)
搞了一下午,浪费了不少时间,特别记录一下;
在弹出第一个框的时候,点击对应操作,然后引发第二个框,此时需要在父DOM中添加一个子DOM,大概代码如下:
const rootElement = document.createElement("div");
root = createRoot(rootElement);
rootElement.id = dialogName;
const parent = document.getElementById(parent_id);
parent.appendChild(rootElement);
const closeDialog = (is_success) => {
try {
root.unmount();
rootElement.remove();
} catch (error) {
console.log("error:", error);
rootElement.remove();
} finally {
resolve(is_success);
}
}
root.render(<ComponentXXX cancel={closeDialog} />);
总是在关闭的时候,报错误tabbable错误,开始以为是DOM操作出了问题,然后各种试验,添加dom层数,以及dom里面的各种操作,直至添加了input 元素之后,才发现能避免这个错误crash,此时才意识到可能是tabbable导致的动态加"div" 元素无法获取焦点,所以在react unmount modal之后页面无法获取焦点,导致crash,后来加了"rootElement.tabIndex = "0"; 改成如下代码:
const rootElement = document.createElement("div");
root = createRoot(rootElement);
rootElement.id = dialogName;
rootElement.tabIndex = "0";
const parent = document.getElementById(parent_id);
parent.appendChild(rootElement);
总结:这个错误机器隐藏,主要是创建的"div" 默认是不可以获取焦点的,而弹出层又是react的modal框,消失的时候,事件冒泡的承接顺序错误,直接导致程序crash;这种错误,主要原因还是对底层dom操作以及相应事件没搞明白,还得加强学习呐!浪费了不少时间!