reactjs - Tip 'MutableRefObject' nije moguće dodijeliti tipu 'LegacyRef | undefined'


S obzirom na ovaj vrlo jednostavan komponent:

const InputElement => React.forwardRef((props:any, ref) => {
    const handleRef = React.useRef<HTMLInputElement|undefined>()
    React.useImperativeHandle(ref, () => ({
        setChecked(checked:boolean) {
            if (handleRef.current) {
                handleRef.current.checked = checked;
            }
        }
    }), []);
    return (
        <input ref={ handleRef } type="checkbox" />  {/* <-- error here */}
    )
})

Imam ovu pogrešku:

Type 'MutableRefObject<HTMLInputElement | undefined>' is not assignable to type 'LegacyRef<HTMLInputElement> | undefined'.
  Type 'MutableRefObject<HTMLInputElement | undefined>' is not assignable to type 'RefObject<HTMLInputElement>'.
    Types of property 'current' are incompatible.
      Type 'HTMLInputElement | undefined' is not assignable to type 'HTMLInputElement | null'.
        Type 'undefined' is not assignable to type 'HTMLInputElement | null'.ts(2322)

Što ovo znači? Kako popraviti ovu pogrešku?

Odgovor #1

Da biste ispravili pogrešku, trebali biste proslijediti null kao početnu vrijednost u useRef hook. Ne morate dodavati | undefined:

React.useRef<HTMLInputElement>(null)

Poruka o pogrešci kaže da ref svojstvo očekuje ref tipa HTMLInputElement | null, ali ako ništa ne proslijedite useRef hooku, on se evaluira kao HTMLInputElement | undefined i zato dobivate poruku o pogrešci:

Type 'undefined' is not assignable to type 'HTMLInputElement | null'

Da biste bolje razumjeli što se događa, evo kako biste mogli reproducirati istu pogrešku s jednostavnom funkcijom:

// This function expects a ref similar to how an element like <input> does
const someFunction = (ref: RefObject<HTMLElement | null>) => {};

// the type of `ref` below will be RefObject<HTMLElement | undefined>
const ref = useRef<HTMLElement>();

// throws `Type 'undefined' is not assignable to type 'HTMLElement | null'`
someFunction(ref);

Baš kao što dobivate grešku u ref svojstvu, dobit ćete istu grešku i u pozivu funkcije u posljednjem retku. Ako proslijedite null u useRef hook, tip ref bi tada postao RefObject<HTMLElement | null>, što je kompatibilno s onim što funkcija očekuje, stoga se ne pojavljuje greška.

Odgovor #2

Imam istu pogrešku kao sljedeću:

Type 'MutableRefObject<undefined>' is not assignable to type 'LegacyRef<Element> | undefined'.
Type 'MutableRefObject<undefined>' is not assignable to type 'RefObject<Element>'.
Types of property 'current' are incompatible.
Type 'undefined' is not assignable to type 'Element | null'.ts(2322)
<Box
    as="button"
    sx={styles.notificationIconWrapper}
    ref={notificationsTrayRef}
    onClick={(e) => {
        e.preventDefault();
        setShowDropdown(!showDropdown);
    }}
    aria-label="notification-toggle-button"
>

Prethodni kodovi su sljedeći:

const notificationsTrayRef = useRef();
useOnClickOutside(notificationsTrayRef, () => setShowDropDown(false));
export function useOnClickOutside(
    ref: React.MutableRefOBject<HTMLElement | undefined>,
    handler: any,
): void {

Prosljeđivanjem null kao početne vrijednosti u useRef hooku i kao prvog parametra tipa ref u useOnClickOutside hooku, pogreška je s moje strane sada popravljena.

Ažurirani kodovi su navedeni u nastavku.

Datoteka komponente:

const notificationsTrayRef = useRef(null);
useOnClickOutside(notificationsTrayRef, () => setShowDropdown(false));

Datoteka prilagođenog hooka:

export function useOnClickOutside(
ref: React.MutableRefObject<HTMLElement | undefined | null>,
handler: any,
): void {...}

Nadam se da će ovo pomoći drugima.

Povezani članci