Definitelytyped: [@types/react] useRef tipe pengembalian bentrok dengan tipe prop ref

Dibuat pada 19 Mei 2019  ·  12Komentar  ·  Sumber: DefinitelyTyped/DefinitelyTyped

  • [x] Saya mencoba menggunakan paket @types/16.8.17 dan mengalami masalah.
  • [x] Saya mencoba menggunakan tsc versi stabil terbaru. https://www.npmjs.com/package/typescript
  • [x] Saya punya pertanyaan yang tidak pantas untuk StackOverflow . (Silakan ajukan pertanyaan yang sesuai di sana).
Type 'MutableRefObject<HTMLDivElement | undefined>' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
  Type 'MutableRefObject<HTMLDivElement | undefined>' is not assignable to type 'RefObject<HTMLDivElement>'.
    Types of property 'current' are incompatible.
      Type 'HTMLDivElement | undefined' is not assignable to type 'HTMLDivElement | null'.
        Type 'undefined' is not assignable to type 'HTMLDivElement | null'.

Komentar yang paling membantu

Solusi yang sedikit lebih rapi adalah dengan mengatur initialValue ke null dalam panggilan fungsi useRef

const componentRef = useRef<HTMLDivElement>(null);

ini memastikan bahwa componentRef = HTMLDivElement | null yang diharapkan oleh prop ref daripada HTMLDivElement | undefined .

Semua 12 komentar

EDIT 2: Abaikan solusi saya, gunakan yang di bawah ini :)

Saat ini saya memiliki masalah yang sama, apakah Anda sudah menemukan solusinya?

EDIT: Saya sekarang menggunakan ini, memang tidak begitu cantik, solusi:

const inputField = React.useRef() as React.MutableRefObject<HTMLInputElement>;

Ditemukan di sini: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/28884#issuecomment -471341041

Solusi yang sedikit lebih rapi adalah dengan mengatur initialValue ke null dalam panggilan fungsi useRef

const componentRef = useRef<HTMLDivElement>(null);

ini memastikan bahwa componentRef = HTMLDivElement | null yang diharapkan oleh prop ref daripada HTMLDivElement | undefined .

@shane935 Anda telah membuat hari saya menyenangkan pak

Menurut saya undefined harus ditambahkan ke RefObject<T>.current seperti:

//index.ts, line 80
interface RefObject<T> {
   readonly current: T | null;
}

jadi terbaca

//index.ts, line 80
interface RefObject<T> {
   readonly current: T | null | undefined;
}

Ini bukan bug, ini menangkap kesalahan pengetikan yang sah.

Untuk detail lebih lanjut, lihat https://github.com/DefinitelyTyped/DefinitelyTyped/pull/38228#issuecomment -529749802

Seperti yang dikatakan @Jessidhia , ini bukan bug , mungkin Anda harus menulis seperti ini.

import React, {
  forwardRef,
  ForwardRefRenderFunction,
  useImperativeHandle,
  useRef,
  PropsWithChildren,
} from "react";

interface Props {}
interface Ref {
  value: string;
  setValue: (value: string) => void;
}

const InputEmail: ForwardRefRenderFunction<Ref, PropsWithChildren<Props>> = (
  props,
  ref
) => {
  // hooks
  const inputElement = useRef<HTMLInputElement | null>(null);
  useImperativeHandle(ref, () => {
    return {
      value: inputElement.current ? inputElement.current.value : "",
      setValue: (value: string) => {
        inputElement.current && (inputElement.current.value = value);
      },
    };
  });

  // render
  return (
    <div>
      <input
        type="text"
        ref={inputElement}
        defaultValue="[email protected]"
        disabled
      />
    </div>
  );
};

const Component = forwardRef(InputEmail);

export default Component;

Saya tidak yakin ini akan memperbaiki masalah semua orang, dan saya bukan ahli dalam hal ini, tetapi setelah melihat pengetikan dari apa yang saya lewati sebagai referensi dan jenis referensi sebenarnya dari komponen yang saya masukkan referensi ke , sepertinya saya memiliki antarmuka yang salah.

Saya awalnya memiliki antarmuka alat peraga seperti itu untuk komponen penerima:

type TextboxProps = CustomProps & React.HTMLProps<HTMLInputElement>

yang saya ubah menjadi:

type TextboxProps = CustomProps & React.HTMLAttributes<HTMLInputElement>

kesalahan pengetikan kemudian menghilang.

Saya tidak akan berpura-pura tahu lebih banyak daripada saya, tetapi melihat ke dalam pengetikan untuk antarmuka HTMLProps dan tipe fungsi React.forwardRef() Anda dapat melihat bahwa itu menggunakan RefAttributes. Tepat di atasnya, Anda dapat melihat ClassAttributesketik HTMLProps itusedang diperluas, yang mendefinisikan LegacyRefjenis yang saya yakini menyebabkan masalah pengetikan saya.

Sepertinya proyek ini memiliki 3 kelebihan untuk useRef() , apakah kita memerlukan ketiganya? Sepertinya kasing useRef<T>(null) adalah yang paling sering digunakan pengembang.

    function useRef<T>(initialValue: T): MutableRefObject<T>;
    function useRef<T>(initialValue: T|null): RefObject<T>;
    function useRef<T = undefined>(): MutableRefObject<T | undefined>;
  1. Apa kasus penggunaan yang diharapkan dari dua kelebihan yang bisa berubah?
  2. Apakah ada cara lain yang dapat didukung agar pengguna dapat lebih mudah menemukan kelebihan yang "benar"?

Saya punya RefObject :

Screen Shot 2020-08-23 at 1 06 16 PM

Saya meneruskannya ke komponen Panel saya sebagai prop ref :

Screen Shot 2020-08-23 at 1 06 04 PM

Saya mencoba mengkonsumsi w/ forwardRef , menjadi MutableRefObject :

Screen Shot 2020-08-23 at 1 06 56 PM

Saya sekarang tidak dapat menggunakan properti .current :

Screen Shot 2020-08-23 at 1 10 27 PM

@Jessidhia @osf2e saran Anda sepertinya tidak berlaku di sini.

Solusi yang harus saya gunakan:

        if (ref && (ref as RefObject<HTMLDivElement>).current) {
              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
              (ref as RefObject<
                HTMLDivElement
              >)!.current!.style.height = `${containerHeight}px`;
            }

Menggunakan react-native-web, saya harus menggunakan.

import {RefObject} from 'react';
// ...
const myRef = useRef() as RefObject<View>

Saya memiliki masalah dengan Ref untuk elemen Input
Jadi saya beralih dari useRef<HTMLDivElement>() -> useRef<HTMLInputElement>() dan berhasil OK

@joshribakoff Anda juga dapat mengetik parameter secara langsung

export const Panel = React.forwardRef((props: PanelProps, ref: React.RefObject<HTMLDivElement>) => {

Dengan begitu Anda tidak perlu mengetik ketika mengakses referensi Anda.
Tapi aku masih tidak mengerti mengapa kita harus melakukan ini...

Apakah halaman ini membantu?
0 / 5 - 0 peringkat