@types/16.8.17
et j'ai eu des problèmes.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'.
EDIT 2 : Ne tenez pas compte de ma solution, utilisez celle ci-dessous :)
J'ai actuellement le même problème, avez-vous déjà trouvé une solution par hasard ?
EDIT : J'utilise maintenant cette solution, certes pas si jolie :
const inputField = React.useRef() as React.MutableRefObject<HTMLInputElement>;
Trouvé ici : https://github.com/DefinitelyTyped/DefinitelyTyped/issues/28884#issuecomment -471341041
Une solution légèrement plus simple consiste à définir initialValue sur null dans l'appel de fonction useRef
const componentRef = useRef<HTMLDivElement>(null);
cela garantit que componentRef = HTMLDivElement | null
qui est ce que la prop ref attend plutôt que HTMLDivElement | undefined
.
@shane935 vous avez fait ma journée monsieur 🙌🏻
Il me semble que undefined
devrait être ajouté à RefObject<T>.current
comme :
//index.ts, line 80
interface RefObject<T> {
readonly current: T | null;
}
donc ça se lit
//index.ts, line 80
interface RefObject<T> {
readonly current: T | null | undefined;
}
Ce n'est pas un bogue, c'est une erreur de frappe légitime.
Pour plus de détails, voir https://github.com/DefinitelyTyped/DefinitelyTyped/pull/38228#issuecomment -529749802
Tout comme @Jessidhia le dit, ce n'est pas un bug, peut-être devriez-vous écrire comme ça.
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;
Je ne suis pas sûr que cela résoudra le problème de tout le monde, et je ne suis pas un expert en la matière, mais après avoir examiné les typages de ce que je transmettais en tant que référence et le type de référence réel du composant dans lequel je transmettais la référence , il semblait que j'avais mal les interfaces.
J'avais initialement une interface d'accessoires comme celle-ci pour le composant de réception :
type TextboxProps = CustomProps & React.HTMLProps<HTMLInputElement>
que j'ai remplacé par :
type TextboxProps = CustomProps & React.HTMLAttributes<HTMLInputElement>
l'erreur de frappe a alors disparu.
Je ne vais pas prétendre en savoir plus que moi, mais en examinant les typages de l'interface HTMLProps et le type de fonction React.forwardRef(), vous pouvez voir qu'il utilise RefAttributes
Il semble que ce projet ait 3 surcharges pour useRef()
, avons-nous besoin des 3 ? Il semble que le cas useRef<T>(null)
soit celui que les développeurs utiliseront la plupart du temps.
function useRef<T>(initialValue: T): MutableRefObject<T>;
function useRef<T>(initialValue: T|null): RefObject<T>;
function useRef<T = undefined>(): MutableRefObject<T | undefined>;
J'ai RefObject
:
Je le passe à mon composant Panel
en tant que prop ref
:
J'essaie de consommer w/ forwardRef
, ça devient MutableRefObject
:
Je ne peux plus utiliser la propriété .current
:
@Jessidhia @osf2e votre suggestion ne semble pas applicable ici.
La solution de contournement à laquelle j'ai dû recourir:
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`;
}
En utilisant react-native-web, je devais utiliser.
import {RefObject} from 'react';
// ...
const myRef = useRef() as RefObject<View>
J'ai eu ce problème avec une Ref pour un élément Input
Donc je suis passé de useRef<HTMLDivElement>()
-> useRef<HTMLInputElement>()
et ça a bien fonctionné
@joshribakoff Vous pouvez également taper les paramètres directement
export const Panel = React.forwardRef((props: PanelProps, ref: React.RefObject<HTMLDivElement>) => {
De cette façon, vous ne devriez pas avoir à transtyper lors de l'accès à votre ref.
Mais je ne comprends toujours pas pourquoi nous devons faire cela...
Commentaire le plus utile
Une solution légèrement plus simple consiste à définir initialValue sur null dans l'appel de fonction useRef
const componentRef = useRef<HTMLDivElement>(null);
cela garantit que componentRef =
HTMLDivElement | null
qui est ce que la prop ref attend plutôt queHTMLDivElement | undefined
.