You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击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 };
};

关键修改点

  1. 移除window.load事件监听:路由切换属于SPA内部跳转,页面不会重新加载,该事件对返回场景完全无效。
  2. 主动调用handleResize:在useLayoutEffect执行时直接读取元素尺寸,覆盖组件首次挂载、路由返回重新挂载等所有场景。
  3. 增加空值判断:防止组件卸载或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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:20:41