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

React中动态设置offsets状态时console.log持续输出null的问题

React中动态设置offsets状态时console.log持续输出null的问题

我看了你的代码,发现几个关键问题导致你console.log一直输出null,而且没法在组件挂载时就获取到元素的宽高,咱们一步步来解决:

1. 多余的Ref嵌套导致引用混乱

你同时用了createRef和useRef来包裹引用,这完全是多此一举——gridCol = useRef(gridColRef)这个操作会让你的ref引用层级混乱,直接用useRef(组件生命周期内保持同一引用,比createRef更适合这个场景)就足够了。

把原来的:

let gridColRef = createRef();
let gridCol = useRef(gridColRef);

简化成:

const gridColRef = useRef(null);

之后直接通过gridColRef.current就能访问到DOM元素,不用再套一层current.current。

2. 组件挂载时未主动获取初始宽高

你的代码只有在窗口resize时才会更新offsets状态,但组件刚挂载时并没有主动去获取一次元素的宽高,所以初始的offsets一直是{ offset_width: null, offset_height: null },这就是console.log输出null的核心原因。

3. Resize事件未清理且触发过于频繁

你在useEffect里添加了resize监听,但没有在组件卸载时移除它,可能导致内存泄漏;而且每次窗口resize都会立刻调用setOffsets,频繁触发组件重渲染,性能不够友好,最好加防抖来限制触发频率。


修正后的完整代码

我把所有问题都修复了,还加了详细注释:

import { useEffect, useRef, useState } from "react";
import Section from "./Section";
import QuestionAnswer from "./QuestionAnswer";

export default function FAQ() {
  const [offsets, setOffsets] = useState({ offset_width: null, offset_height: null });
  // 直接用useRef保持组件生命周期内的统一引用
  const gridColRef = useRef(null);

  // 封装复用的宽高更新函数
  const updateOffsets = () => {
    if (gridColRef.current) {
      const width = gridColRef.current.offsetWidth;
      const height = gridColRef.current.offsetHeight;
      setOffsets({ offset_width: width, offset_height: height });
    }
  };

  useEffect(() => {
    // 组件挂载时主动获取一次初始宽高
    updateOffsets();

    // 给resize事件加防抖,300ms内只执行一次,避免频繁重渲染
    const debouncedUpdate = () => {
      clearTimeout(window.resizeTimeout);
      window.resizeTimeout = setTimeout(updateOffsets, 300);
    };

    // 添加resize事件监听
    window.addEventListener("resize", debouncedUpdate);

    // 组件卸载时移除监听、清理定时器,防止内存泄漏
    return () => {
      window.removeEventListener("resize", debouncedUpdate);
      clearTimeout(window.resizeTimeout);
    };
  }, []); // 依赖空数组,只在挂载/卸载时执行

  return (
    <Section section-name="faq">
      <h1 className="faq-header">Frequently asked questions</h1>
      <div className="grid-container">
        <div className="grid-col" ref={gridColRef}>
          <QuestionAnswer
            offsets={offsets}
            question="What is Electrodermal Activity (EDA)?"
            answers={[
              "EDA, often referred to as skin conductance, measures changes in the electrical conductivity of the skin. It's a physiological response linked to emotional arousal and stress.",
            ]}
          />
        </div>
      </div>
    </Section>
  );
}

额外小提示

JSX属性推荐使用驼峰命名法,比如把<Section section-name="faq">改成<Section sectionName="faq">,这是React的常规写法,避免和HTML自定义属性混淆。

备注:内容来源于stack exchange,提问作者Mig Rivera Cueva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:09:34