为什么在尝试使用 ref 时打字稿会抱怨?

why is typescript complaining when trying to use ref in react?

我正在使用 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 类型脚本模板中使用它时,它抱怨 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.xml 中使用 "strict": false 绕过了这个问题。但需要在严格模式下进行。

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

您可以将 ref 转换为从 React 中获取的任何内容。
const ref = useRef(null) as any;

编辑:我想回来提供一个更强类型的解决方案,但 Sakshi 的回答就是这样做的。这是懒惰的修复,所以请遵循他们的解决方案。

试试这个:

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 : ""
    );
  };

这很简单,只需将类型 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);
  }
}, []);