点击react-router NavLink返回后useRef返回undefined问题求助
问题原因分析
你的问题核心在于自定义hook的事件监听覆盖不全,且缺少组件挂载时的主动尺寸读取逻辑:
- 首次加载时
window.load事件会触发,能正常获取元素尺寸;但通过react-router跳转返回首页时,页面并未重新加载,load事件不会再次触发,导致没有时机去读取元素尺寸。 - 组件重新挂载时,
ref.current会被赋值,但你的hook没有主动去读取这个新赋值的元素尺寸,只能等窗口resize时才会更新。 - 未处理
ref.current为null的边界情况,极端场景下可能触发报错。
修复方案
修改你的useGetElementDimensions hook,补充主动读取逻辑并优化事件监听:
import { useCallback, useLayoutEffect, useState } from "react"; export const useGetElementDimensions = (ref) => { const [width, setWidth] = useState(0); const [height, setHeight] = useState(0); const handleResize = useCallback(() => { // 先判断元素是否存在,避免报错 if (!ref.current) return; setWidth(ref.current.offsetWidth); setHeight(ref.current.offsetHeight); }, [ref]); useLayoutEffect(() => { // 组件挂载/更新时主动调用一次,确保拿到最新尺寸 handleResize(); // 保留resize事件监听,处理窗口尺寸变化 window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, [ref, handleResize]); return { width, height }; };
关键修改点
- 移除
window.load事件监听:路由切换属于SPA内部跳转,页面不会重新加载,该事件对返回场景完全无效。 - 主动调用
handleResize:在useLayoutEffect执行时直接读取元素尺寸,覆盖组件首次挂载、路由返回重新挂载等所有场景。 - 增加空值判断:防止组件卸载或ref未完成赋值时,调用DOM属性导致报错。
额外优化建议
其实你可以用纯CSS实现绝对定位元素的居中,完全不需要JS计算尺寸,更简洁且无bug:
// 在HomeStyles.js中修改TextContainer的样式 const TextContainer = styled.div` position: absolute; left: 50%; top: 50%; // 对应原代码中-42px的垂直偏移 transform: translate(-50%, calc(-50% - 42px)); /* 保留原有其他样式 */ `;
之后就可以删除JS中left和top的计算逻辑,彻底规避尺寸监听相关问题。
内容的提问来源于stack exchange,提问作者Lauro235
相关产品推荐
相关产品推荐

