【问题标题】:React - Type 'number | MutableRefObject<any>' is not assignable to type 'LegacyRef<HTMLElement>'反应 - 类型'数字 | MutableRefObject<any>' 不可分配给类型 'LegacyRef<HTMLElement>'
【发布时间】:2022-01-10 03:00:10
【问题描述】:

当我想将 ref 添加到主元素时,会出现以下错误。

错误

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

代码沙盒
https://codesandbox.io/s/scroll-percentage-hook-forked-6bcyw?file=/src/index.tsx

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:
    export default function useScrollPercentage() {
      // ...
      return [scrollRef, Number.isNaN(scrollPercentage) ? 0 : scrollPercentage];
    }
    

    由于您没有给出明确的返回类型,因此打字稿必须推断出一个。假设这是一个数组,而不是元组,因此该数组的类型为(MutableRefObject&lt;any&gt; | number)[],因为它同时包含 ref 对象和数字。这种类型没有任何关于哪些元素在数组的哪些位置的任何信息,所以回到 App 中并不清楚 scrollRef 是一个 ref 还是一个数字。

    如果你希望类型是一个元组[MutableRefObject&lt;any&gt;, number],你需要自己给它一个类型。你可以这样做:

    export default function useScrollPercentage(): [MutableRefObject<any>, number] {
    

    或者你可以继续使用类型推断,但使用as const 给打字稿一个提示,以便推断出更严格的类型:

    return [scrollRef, Number.isNaN(scrollPercentage) ? 0 : scrollPercentage] as const;
    

    【讨论】:

      猜你喜欢
      • 2023-01-03
      • 2022-12-01
      • 1970-01-01
      • 2021-07-01
      • 2017-08-12
      • 2022-08-04
      • 2021-09-23
      • 2020-08-24
      • 1970-01-01
      相关资源
      最近更新 更多