【问题标题】:why is typescript complaining when trying to use ref in react?为什么尝试在反应中使用 ref 时打字稿会抱怨?
【发布时间】:2021-04-26 14:46:27
【问题描述】:

我正在使用 ref 为滚动上的元素设置动画。

  const foo = () => {
    if (!ref.current) return;
    const rect = ref.current.getBoundingClientRect();
    setAnimClass(
      rect.top >= 0 && rect.bottom <= window.innerHeight ? styles.animClass : ""
    );
  };

此代码在 next.js 应用程序中运行良好。但是当我在create-react-app type-script 模板中使用它时,它抱怨Object is possibly 'null'.

if (!ref.current) return; 可以清楚地看出,如果 ref.current 不存在,程序将被返回。但是 TypeScript 在下一行 ref.current.getBoundingClientRect() 上仍然给出错误,指向 ref

如何在不从 typescript 配置中删除 null 检查的情况下解决此问题?

完整文件 - https://github.com/mayank1513/react-contact-app/blob/master/src/components/ContactListItem.tsx

这是完整的项目回购 - https://github.com/mayank1513/react-contact-app

到目前为止,我已经在 tsconfig 中使用 "strict": false 绕过了这个问题。但需要在严格模式下进行。

this 文件中也存在类似问题。即使通过在 tsconfig 中设置 "strict": false 也无法解决此问题。现在我只依赖document.getElementById()——在第 65 行左右

【问题讨论】:

  • 可选链接可能会抑制错误ref?.current?.getBoundingClientRect()
  • 试试这个。 ref?.current!.getBoundingClientRect()

标签: javascript reactjs typescript use-ref


【解决方案1】:

试试这个:

const ref = useRef() as RefObject<HTMLDivElement>;

const foo = () => {
    if (!ref.current) return;
    const rect = ref.current.getBoundingClientRect();
    setAnimClass(
      rect.top >= 0 && rect.bottom <= window.innerHeight ? styles.animClass : ""
    );
  };

【讨论】:

  • 这里的 RefObject 是什么?打字稿抱怨 RefObject
  • 您还必须添加导入语句。添加此import { RefObject } from "react";
  • 此问题已通过在 jsx 中使用 ref={ref} 时出现错误得到解决。使用 useRef() 效果很好,但我认为如果 jsx 也能正常工作,这是更合适的方法
  • 告诉我你的代码你在哪里使用你的ref
  • 嗨,这是一个愚蠢的错误。我在输入类型中使用了 ref。解决了这个问题。
【解决方案2】:

您可以将 ref 转换为任何从 react 获得的。
const ref = useRef(null) as any;

编辑:我想回来并给出一个更强类型的解决方案,但 Sakshi 的回答就是这样做的。这是惰性修复,因此请遵循他们的解决方案。

【讨论】:

    【解决方案3】:

    这很简单,只需将类型HTMLDivElement 添加到useRef,错误就不再出现了:

    const ref = useRef<HTMLDivElement>(null);
    

    奖励:您应该始终删除 useEffect 中的侦听器:

    useEffect(() => {
      foo();
      window.addEventListener("scroll", foo);
      window.addEventListener("resize", foo);
      return () => {
        window.removeEventListener("scroll", foo);
        window.removeEventListener("resize", foo);
      }
    }, []);
    

    【讨论】:

      猜你喜欢
      • 2016-05-22
      • 1970-01-01
      • 2018-10-14
      • 2020-01-14
      • 2016-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-15
      相关资源
      最近更新 更多