繁体   English   中英

将 useRef 与 TypeScript 一起使用时出现问题

[英]Issue using useRef with TypeScript

我有以下代码;

应用程序.tsx

export default function App() {
  const [canvasRef, canvasWidth, canvasHeight] = useCanvas();
  return (
    <div>
      <canvas
        ref={canvasRef}
      />
    </div>
  )
}

使用Canvas.ts

import { useRef, useEffect } from "react";

const canvasWidth = 1200;
const canvasHeight = 600;

export default function useCanvas() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  return [canvasRef, canvasWidth, canvasHeight]
}

是的,这正是我的代码中的内容,但是,我在来自 Vscode 的 App.tsx 中收到以下错误;

(JSX attribute) React.ClassAttributes<HTMLCanvasElement>.ref?: string | React.RefObject<HTMLCanvasElement> | ((instance: HTMLCanvasElement | null) => void) | null | undefined
Type 'number | RefObject<HTMLCanvasElement>' is not assignable to type 'string | RefObject<HTMLCanvasElement> | ((instance: HTMLCanvasElement | null) => void) | null | undefined'.
  Type 'number' is not assignable to type 'string | RefObject<HTMLCanvasElement> | ((instance: HTMLCanvasElement | null) => void) | null | undefined'.ts(2322)
index.d.ts(143, 9): The expected type comes from property 'ref' which is declared here on type 'DetailedHTMLProps<CanvasHTMLAttributes<HTMLCanvasElement>, HTMLCanvasElement>'

任何意见,将不胜感激。

function useCanvas() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  return [canvasRef, canvasWidth, canvasHeight]
}

由于您没有为返回值指定类型,因此 typescript 将推断它。 在推断数组的类型时, typescript 将假定它是普通数组,而不是tuple

为了简化它,假设你要返回这个:

function () {
  return [1, 'a'];
}

Typescript 将推断类型为(number | string)[] 换句话说,一个任意长度的数组,其中每个元素都可以是字符串的数字。 不会将类型推断为[number, string] 因此,如果您尝试与该数组的索引 0 进行交互,typescript 将无法告诉您它绝对是一个数字,只能告诉您它是一个数字或一个字符串。

所以你的第一个选择是给你要返回的东西一个明确的类型。 在我的简化案例中,它将是:

function () {
  const result: [number, string] = [1, 'a'];
  return result;
}

// or
function (): [number, string] {
  return [1, 'a'];
}

// or
function () {
  return [1, 'a'] as [number, string];
}

我不确定您的代码是否正确的类型,但您可以检查变量并找出答案。

另一种选择,可能是更简单的选择,是使用as const来帮助 typescript 推断类型。 as const告诉它的那样,这永远不会改变,因此它将把它视为一个元组而不是一个数组。

function useCanvas() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  return [canvasRef, canvasWidth, canvasHeight] as const;
}

您的自定义钩子的返回类型是(number | React.MutableRefObject<HTMLCanvasElement>)[]因为 typescript 推断它返回包含这些类型的数组。 这就是为什么App.tsx中的解构变量没有正确输入(如果你 hover 它们,你会看到它们都是类型number | React.MutableRefObject<HTMLCanvasElement> )。

你需要的是使用一个元组来告诉 typescript 这个数组中到底包含什么。

您可以像这样将输入信息添加到您的自定义挂钩中:

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

const canvasWidth = 1200;
const canvasHeight = 600;

export default function useCanvas(): [MutableRefObject<HTMLCanvasElement>, number, number] {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  return [canvasRef, canvasWidth, canvasHeight]
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM