React项目document.readystatechange事件未触发问题求助
问题排查与解决方案
核心原因
你的代码仅监听readystatechange事件,但当组件挂载时,文档可能已经处于complete状态——这个事件只有在文档状态从loading→interactive→complete发生变化时才会触发,若组件挂载时机晚于文档完成时机,事件回调就不会被执行。
旧电脑上正常是因为组件挂载比文档完成早,能捕获到状态变化;新电脑可能因浏览器缓存、本地性能更优,文档提前加载完成,组件挂载时状态已经是complete,所以事件从未触发。另外你的useEffect没有设置依赖数组,会导致组件每次渲染都重复注册/移除事件,属于不必要的性能损耗。
修复后的代码
function useElementDimension(elementId: string) { const [dimensions, setDimensions] = useState({ height: 0, width: 0 }); useEffect(() => { function updateDimensions() { const stage = document.getElementById(elementId); if(stage === null) return; setDimensions({width: stage.clientWidth, height: stage.clientHeight}); } // 先检查当前文档状态,已完成则直接更新尺寸 if(document.readyState === "complete") { updateDimensions(); } // 监听文档状态变化和窗口resize(适配flexbox动态尺寸变化) document.addEventListener('readystatechange', updateDimensions); window.addEventListener('resize', updateDimensions); return () => { document.removeEventListener('readystatechange', updateDimensions); window.removeEventListener('resize', updateDimensions); }; }, [elementId]); // 添加依赖数组,仅在elementId变化时重新执行 return dimensions; }
额外说明
- 将原
onLoaded重命名为updateDimensions,更贴合功能定位:不仅在文档就绪时执行,后续窗口resize时也能更新尺寸,适配flexbox布局的动态变化。 - 新增窗口
resize事件监听,因为flexbox元素尺寸可能随窗口大小改变,仅在文档就绪时获取一次尺寸无法覆盖所有场景。 - 给
useEffect添加[elementId]依赖,确保只有目标元素ID变化时才重新绑定事件,避免无效重复执行。
内容的提问来源于stack exchange,提问作者Ivan Lo Greco
相关产品推荐
相关产品推荐

