类型“MutableRefObject<undefined>”不可分配给类型“LegacyRef<HTMLDivElement> | 不明确的'

Sho*_*har 6 javascript typescript reactjs next.js

我设置了一个自定义挂钩,它获取一个ref对象并观察它:

import { useState, useEffect, MutableRefObject } from "react";

const UseOnScreen = (ref: MutableRefObject<undefined>) => {
  const [isIntersecting, setIntersecting] = useState(false);
  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) =>
      setIntersecting(entry.isIntersecting)
    );
    if (ref.current) {
      observer.observe(ref.current);
    }
  });
  return isIntersecting;
};
export default UseOnScreen;
Run Code Online (Sandbox Code Playgroud)

接下来,在我的页面组件中,我声明了一个refusing useRef()

import { useRef } from "react";
import UseOnScreen from "../hooks/UseOnScreen";
import About from "./about";

export default function Home() {
  const aboutRef = useRef();
  const aboutRefValue = UseOnScreen(aboutRef);

  return (
     <>
         {/* other components */}
         <div ref={aboutRef}>{aboutRefValue && <About />}</div>
     </>
  );
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下错误:

Type 'MutableRefObject<undefined>' is not assignable to type 'LegacyRef<HTMLDivElement> | undefined'.
  Type 'MutableRefObject<undefined>' is not assignable to type 'RefObject<HTMLDivElement>'.
    Types of property 'current' are incompatible.
      Type 'undefined' is not assignable to type 'HTMLDivElement | null'.ts(2322)
index.d.ts(138, 9): The expected type comes from property 'ref', which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'
Run Code Online (Sandbox Code Playgroud)

关于此错误的奇怪事实是,尽管这在我的编辑器中给出了错误,但代码仍然按预期工作。我尝试将 ref 对象的类型设置为LegacyRef<HTMLDivElement> | undefined,但错误仍然存​​在。

我想在我的编辑器中消除这个错误。

You*_*mar 5

MutableRefObject<undefined>,你是说我想要 的 ref undefined;那就是问题所在。将其更改为MutableRefObject<HTMLDivElement | null>并更新您的useRef呼叫,如下所示:

const useOnScreen = (ref: MutableRefObject<HTMLDivElement | null>) => {
  const [isIntersecting, setIntersecting] = useState(false);
  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) =>
      setIntersecting(entry.isIntersecting)
    );
    if (ref.current) {
      observer.observe(ref.current);
    }
  });
  return intersecting;
};
export default useOnScreen;
Run Code Online (Sandbox Code Playgroud)
export default function Home() {
  const aboutRef = useRef<HTMLDivElement | null>(null);
  const aboutRefValue = useOnScreen(aboutRef);

  return (
    <>
      {/* other components */}
      <div ref={aboutRef}>
        {aboutRefValue && <div>Your about was here</div>}
      </div>
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)