reactjs - React - 类型 'number | MutableRefObject' 不能分配给类型 'LegacyRef'
当我想给主元素添加引用时,出现以下错误。
错误
Type 'number | MutableRefObject<any>' is not assignable to type 'LegacyRef<HTMLElement>'.
Type 'number' is not assignable to type 'LegacyRef<HTMLElement>'
如何修复它?
index.tsx
import React from "react";
import ReactDOM from "react-dom";
import useScrollPercentage from "./useScrollPercentage";
// reset styles
Object.assign(document.body.style, {
overflow: "hidden",
margin: "0"
});
function App() {
const [scrollRef, scrollPercentage] = useScrollPercentage();
return (
// attach scrollRef to scroll container
<main ref={scrollRef} style={{ height: "100vh", overflowY: "scroll" }}>
{/* Simulate overflowing content */}
<div style={{ height: 3000 }} />
{/* Display scroll percentage */}
<h1 style={{ position: "fixed", top: 10, left: 10 }}>
{`${scrollPercentage}%`}
</h1>
</main>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
useScrollPercentage.js
import { useRef, useState, useEffect } from "react";
export default function useScrollPercentage() {
const scrollRef = useRef(null);
const [scrollPercentage, setScrollPercentage] = useState(NaN);
const reportScroll = e => {
setScrollPercentage(getScrollPercentage(e.target));
};
useEffect(
() => {
const node = scrollRef.current;
if (node !== null) {
node.addEventListener("scroll", reportScroll, { passive: true });
if (Number.isNaN(scrollPercentage)) {
setScrollPercentage(getScrollPercentage(node));
}
}
return () => {
if (node !== null) {
node.removeEventListener("scroll", reportScroll);
}
};
},
[scrollPercentage]
);
return [scrollRef, Number.isNaN(scrollPercentage) ? 0 : scrollPercentage];
}
function getScrollPercentage(element) {
if (element === null) {
return NaN;
}
const height = element.scrollHeight - element.clientHeight;
return Math.round((element.scrollTop / height) * 100);
}
Codesandbox
https://codesandbox.io/s/scroll-percentage-hook-forked-6bcyw?file=/src/index.tsx
答案#1
export default function useScrollPercentage() {
// ...
return [scrollRef, Number.isNaN(scrollPercentage) ? 0 : scrollPercentage];
}
由于你没有给出明确的返回类型,TypeScript 必须进行推断。它会假设这是一个数组,而不是元组,因此数组的类型是 (MutableRefObject<any> | number)[],因为它包含了 ref 对象和数字。这个类型没有关于数组中各元素位置的任何信息,因此在 App 中,不清楚 scrollRef 是 ref 还是数字。
如果你希望类型是一个元组 [MutableRefObject<any>, number],你需要自己为它指定类型。你可以这样做:
export default function useScrollPercentage(): [MutableRefObject<any>, number] {
或者你可以继续使用类型推断,但使用 as const 提示 TypeScript,这样它会推断出更严格的类型:
return [scrollRef, Number.isNaN(scrollPercentage) ? 0 : scrollPercentage] as const;
