Definitelytyped: [@ أنواع / رد فعل] useRef يتعارض نوع الإرجاع مع نوع الخاصية ref

تم إنشاؤها على ١٩ مايو ٢٠١٩  ·  12تعليقات  ·  مصدر: DefinitelyTyped/DefinitelyTyped

  • [x] حاولت استخدام الحزمة @types/16.8.17 وواجهت مشاكل.
  • [x] حاولت استخدام أحدث إصدار مستقر من tsc. https://www.npmjs.com/package/typescript
  • [x] لدي سؤال غير مناسب لـ StackOverflow . (يرجى طرح أي أسئلة مناسبة هناك).
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'.

التعليق الأكثر فائدة

الحل الأكثر إتقانًا هو تعيين قيمة initialValue إلى قيمة خالية في استدعاء دالة useRef

const componentRef = useRef<HTMLDivElement>(null);

هذا يضمن أن componentRef = HTMLDivElement | null وهو ما يتوقعه الخاصية ref بدلاً من HTMLDivElement | undefined .

ال 12 كومينتر

تحرير 2: تجاهل الحل الخاص بي ، استخدم الحل أدناه :)

لدي نفس المشكلة حاليًا ، هل وجدت حلًا بالفعل بأي فرصة؟

تحرير: أنا الآن أستخدم هذا الحل ، من المسلم به أنه ليس جميلًا:

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

وجدت هنا: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/28884#issuecomment -471341041

الحل الأكثر إتقانًا هو تعيين قيمة initialValue إلى قيمة خالية في استدعاء دالة useRef

const componentRef = useRef<HTMLDivElement>(null);

هذا يضمن أن componentRef = HTMLDivElement | null وهو ما يتوقعه الخاصية ref بدلاً من HTMLDivElement | undefined .

@ shane935 لقد جعلت يومي سيدي 🙌🏻

يبدو لي أنه يجب إضافة undefined إلى RefObject<T>.current مثل:

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

لذلك يقرأ

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

إنه ليس خطأ ، إنه يصطاد خطأ طباعة مشروعًا.

لمزيد من التفاصيل ، راجع https://github.com/DefinitelyTyped/DefinitelyTyped/pull/38228#issuecomment -529749802

تمامًا كما تقول Jessidhia ، هذا ليس خطأ ، ربما يجب أن تكتب هكذا.

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;

لست متأكدًا من أن هذا سيؤدي إلى حل مشكلة الجميع ، ولست خبيرًا في هذه الأشياء ، ولكن بعد النظر في كتابة ما كنت أمرره كمرجع ونوع المرجع الفعلي للمكون الذي كنت أقوم بتمرير المرجع إليه ، بدا الأمر كما لو كان لدي واجهات خاطئة.

كان لدي في البداية واجهة من الدعائم مثل ذلك لمكون الاستلام:

type TextboxProps = CustomProps & React.HTMLProps<HTMLInputElement>

التي غيرت إلى:

type TextboxProps = CustomProps & React.HTMLAttributes<HTMLInputElement>

ثم اختفى خطأ الكتابة.

لن أتظاهر بأنني أعرف أكثر مما أعرف ، ولكن بالنظر إلى كتابة واجهة HTMLProps ونوع وظيفة React.forwardRef () ، يمكنك أن ترى أنها تستخدم RefAttributes. فوق ذلك بقليل ، يمكنك رؤية سمات ClassAttributesاكتب ذلك HTMLPropsيمتد ، والذي يحدد LegacyRefالنوع الذي أعتقد أنه تسبب في مشكلتي في الكتابة.

يبدو أن هذا المشروع يحتوي على 3 أحمال زائدة مقابل useRef() ، هل نحتاج جميعًا الثلاثة؟ يبدو أن حالة useRef<T>(null) هي الحالة التي يستخدمها المطورون معظم الوقت.

    function useRef<T>(initialValue: T): MutableRefObject<T>;
    function useRef<T>(initialValue: T|null): RefObject<T>;
    function useRef<T = undefined>(): MutableRefObject<T | undefined>;
  1. ما هي حالة الاستخدام المتوقعة لاثنين من الأحمال الزائدة القابلة للتغيير؟
  2. هل هناك طريقة أخرى يمكن دعمها بحيث يتمكن المستخدمون من العثور بسهولة أكبر على الحمل الزائد "الصحيح"؟

لدي RefObject :

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

قمت بتمريره إلى مكون Panel الخاص بي باعتباره العنصر ref :

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

أحاول أن أستهلك w / forwardRef ، فإنه يصبح MutableRefObject :

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

أنا الآن غير قادر على استهلاك الخاصية .current :

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

Jessidhia @ osf2e اقتراحك لا يبدو قابلاً للتطبيق هنا.

الحل البديل الذي اضطررت إلى اللجوء إليه:

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

باستخدام رد فعل أصلي على شبكة الإنترنت ، كان علي استخدام.

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

واجهت هذه المشكلة مع المرجع لعنصر Input
لذلك قمت بالتبديل من useRef<HTMLDivElement>() -> useRef<HTMLInputElement>() وعمل بشكل جيد

joshribakoff يمكنك أيضًا كتابة المعلمات مباشرةً

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

بهذه الطريقة لن تضطر إلى الكتابة عند الوصول إلى المرجع الخاص بك.
لكن ما زلت لا أفهم لماذا يتعين علينا القيام بذلك ...

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات