簡體   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