访问 useRef 中的任何元素都会抛出“未定义”

Posted

技术标签:

【中文标题】访问 useRef 中的任何元素都会抛出“未定义”【英文标题】:Accessing any element in a useRef is throwing 'undefined' 【发布时间】:2021-03-11 14:41:17 【问题描述】:

我正在尝试在 React 中使用 ref,它是一个包含对 DOM 中多个其他 div 的引用的数组。

在 useEffect 中,我映射一个对象来渲染 div,并为每个 div 分配一个 ref。在分配 ref 之前,我使用 createRef 为其实例化一个插槽。

我实际上是在尝试复制 this 答案所建议的做法。

我遇到的问题是我的编译器一直看到undefined。我不确定为什么会这样,但这是我拥有的代码:

import React from "react";

const items = [
  [1, 2, 3, 4, 5],
  [6, 7, 8, 9, 10]
];
export default function Component() 
  const [renderedItems, setRenderedItems] = React.useState();
  const [height, setHeight] = React.useState(0);
  const refsArray = React.useRef([]);

  React.useEffect(() => 
    const heightOfFirstDiv = refsArray.current[0].offsetHeight;
    console.log("heightOfFirstDiv", heightOfFirstDiv); // <-- this is always undefined
    setHeight(heightOfFirstDiv);
  , [renderedItems]);

  React.useEffect(() => 
    setRenderedItems(
      items.map((item, index) => 
        refsArray.current[index] = React.createRef();

        return (
          <div
            ref=refsArray.current[index]
            style= height: 100, width: 40 
          >
            item
          </div>
        );
      )
    );
  , []);

  return (
    <div>
      The height is: height || "undefined"
      renderedItems
    </div>
  );

我在这里做错了什么?

【问题讨论】:

【参考方案1】:

The second answer 你所链接的问题实际上更好更简单。这可以通过callback refs实现:

import React from "react";

const items = [
  [1, 2, 3, 4, 5],
  [6, 7, 8, 9, 10]
];
export default function Component() 
  const [height, setHeight] = React.useState(0);
  const refsArray = React.useRef([]);

  React.useEffect(() => 
    const heightOfFirstDiv = refsArray.current[0].offsetHeight;
    console.log("heightOfFirstDiv", heightOfFirstDiv);
    setHeight(heightOfFirstDiv);
  , [renderedItems]);

  const renderedItems = items.map((item, index) => (
    <div
      ref=(el) => (refsArray.current[index] = el)
      key=index
      style= height: 100, width: 40 
    >
      item
    </div>
  ));

  return (
    <div>
      The height is: height || "undefined"
      renderedItems
    </div>
  );

将渲染的元素存储在组件状态不是一个好的做法,因为它会使组件变得复杂、混乱且难以调试。

【讨论】:

【参考方案2】:

那是因为您的 current[0] 实际上是一个带有 .current 键的对象,您只需编辑 heightOfFirstDiv 以显示该键即可获得所需的值

 const heightOfFirstDiv = refsArray.current[0].current.offsetHeight;

如果您注意到,在您尝试复制的示例中,您会看到他们破坏了这个 .current 键,这就是错误的来源

【讨论】:

以上是关于访问 useRef 中的任何元素都会抛出“未定义”的主要内容,如果未能解决你的问题,请参考以下文章

初始渲染时未定义 useRef 值

选项卡不活动时未定义的元素

为啥此 setInterval 中未定义此 useRef 值?

为啥在这种情况下编译器会抛出“未定义的引用...”错误?

为啥 x-editable-rails gem 会抛出错误:未定义的方法 `xeditable?'?

我不明白为啥会抛出“调用未定义的方法 CI_Input()::event()”