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

如何修复窗口Resize时出现的Cannot read property 'clientWidth' of null错误?

修复React窗口调整时"Cannot read property 'clientWidth' of null"错误

我帮你梳理下问题根源和修复方案:

问题分析

你遇到的错误主要来自两个核心问题:

  1. 变量名混乱:代码里混用了tooltip/setTooltip和allowTooltip/setAllowTooltip,这会直接导致状态更新逻辑失效,甚至让ref的判断逻辑完全出错。
  2. Ref为空时的属性访问:组件渲染初期、状态切换后,或者组件卸载后,divRef.current可能还没挂载到DOM(或已被销毁),直接访问它的scrollWidth/clientWidth就会抛出null错误;加上resize事件没有清理,组件卸载后还会触发,进一步加重这个问题。

修复步骤

  • 统一变量名:把所有tooltip替换成allowTooltip,setTooltip替换成setAllowTooltip,保证状态和更新函数一一对应。
  • 增加Ref存在性校验:每次访问divRef.current的属性前,先判断它是否存在,从根源避免null报错。
  • 清理Resize事件监听:在useEffect的返回函数中移除监听,防止组件卸载后触发事件导致错误,同时避免内存泄漏。
  • 优化useEffect依赖数组:divRef是useRef创建的,它的引用不会变化,不需要放到依赖数组里;只需要监听allowTooltip状态即可。

修复后的完整代码

import React, { useRef, useState, useEffect } from "react";
// 这里假设Tooltip是你使用的组件(比如Material-UI的Tooltip或自定义组件)
import Tooltip from '@mui/material/Tooltip';

const data = [
  "Some short text",
  "Some text that is a little bit longer",
  "Some text that will need to wrap but still fits on two lines",
  "A massive range of hammer drill machines and rotary hammers for SDS-plus accessory tools."
];

const TooltipDiv = props => {
  const divRef = useRef(null);
  const [allowTooltip, setAllowTooltip] = useState(false);

  useEffect(() => {
    // 把判断逻辑封装成函数,方便复用和移除监听
    const checkTextOverflow = () => {
      // 先校验ref是否存在,再访问DOM属性
      if (divRef.current && !allowTooltip) {
        const hasOverflow = divRef.current.scrollWidth > divRef.current.clientWidth;
        setAllowTooltip(hasOverflow);
      }
    };

    // 组件挂载时先检查一次文本是否溢出
    checkTextOverflow();

    // 添加窗口resize监听
    window.addEventListener('resize', checkTextOverflow);

    // 组件卸载时移除监听,防止内存泄漏和报错
    return () => {
      window.removeEventListener('resize', checkTextOverflow);
    };
  }, [allowTooltip]); // 仅监听allowTooltip状态变化

  if (allowTooltip) {
    return (
      <Tooltip title={props.text}>
        <div ref={divRef} className={props.className}>
          {props.text}
        </div>
      </Tooltip>
    );
  }

  return (
    <div ref={divRef} className={props.className}>
      {props.text}
    </div>
  );
};

function App(props) {
  return (
    <>
      {data.map((text, index) => {
        // 给列表元素添加key,符合React列表渲染规范
        return (
          <TooltipDiv 
            key={index}
            text={text} 
            className={props.classes?.listItem} 
          />
        );
      })}
    </>
  );
}

export default App;

额外优化点

我还补充了两个小细节:

  • 给map循环的元素添加了key属性,符合React的列表渲染规范,避免控制台警告。
  • 访问props.classes.listItem时用了可选链?.,防止props.classes不存在时触发报错。

内容的提问来源于stack exchange,提问作者Marcus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:59:02