@types/16.8.17
e tive problemas.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: Desconsidere minha solução, use a abaixo :)
Atualmente estou com o mesmo problema, por acaso você já encontrou uma solução?
EDIT: agora estou usando esta solução, reconhecidamente não tão bonita:
const inputField = React.useRef() as React.MutableRefObject<HTMLInputElement>;
Encontrado aqui: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/28884#issuecomment -471341041
Uma solução um pouco mais limpa é definir o valorInicial como nulo na chamada da função useRef
const componentRef = useRef<HTMLDivElement>(null);
isso garante que componentRef = HTMLDivElement | null
que é o que a prop ref está esperando em vez de HTMLDivElement | undefined
.
@shane935 você fez meu dia senhor 🙌🏻
Parece-me que undefined
deve ser adicionado a RefObject<T>.current
como:
//index.ts, line 80
interface RefObject<T> {
readonly current: T | null;
}
então ele lê
//index.ts, line 80
interface RefObject<T> {
readonly current: T | null | undefined;
}
Não é um bug, está pegando um erro de digitação legítimo.
Para obter mais detalhes, consulte https://github.com/DefinitelyTyped/DefinitelyTyped/pull/38228#issuecomment -529749802
Assim como @Jessidhia diz, não é um bug, talvez você deva escrever assim.
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;
Não tenho certeza se isso resolverá o problema de todos, e não sou especialista nessas coisas, mas depois de olhar para as tipagens do que eu estava passando como ref e o tipo de ref real do componente para o qual eu estava passando o ref , parecia que eu tinha as interfaces erradas.
Inicialmente, eu tinha uma interface de adereços assim para o componente de recebimento:
type TextboxProps = CustomProps & React.HTMLProps<HTMLInputElement>
que alterei para:
type TextboxProps = CustomProps & React.HTMLAttributes<HTMLInputElement>
o erro de digitação então desapareceu.
Não vou fingir que sei mais do que sei, mas olhando para as tipagens para a interface HTMLProps e o tipo de função React.forwardRef() você pode ver que está usando RefAttributes
Parece que este projeto tem 3 sobrecargas para useRef()
, precisamos de todos os 3? Parece que o caso useRef<T>(null)
é o que os desenvolvedores usarão na maioria das vezes.
function useRef<T>(initialValue: T): MutableRefObject<T>;
function useRef<T>(initialValue: T|null): RefObject<T>;
function useRef<T = undefined>(): MutableRefObject<T | undefined>;
Eu tenho RefObject
:
Eu passo para o meu componente Panel
como prop ref
:
Eu tento consumir com forwardRef
, fica MutableRefObject
:
Agora não consigo consumir a propriedade .current
:
@Jessidhia @osf2e sua sugestão não parece aplicável aqui.
A solução alternativa que tive que recorrer:
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`;
}
Usando react-native-web, tive que usar.
import {RefObject} from 'react';
// ...
const myRef = useRef() as RefObject<View>
Eu tive esse problema com um Ref para um elemento Input
Então eu mudei de useRef<HTMLDivElement>()
-> useRef<HTMLInputElement>()
e funcionou bem
@joshribakoff Você também pode digitar os parâmetros diretamente
export const Panel = React.forwardRef((props: PanelProps, ref: React.RefObject<HTMLDivElement>) => {
Dessa forma, você não deve ter que typecast ao acessar seu ref.
Mas ainda não entendo porque temos que fazer isso...
Comentários muito úteis
Uma solução um pouco mais limpa é definir o valorInicial como nulo na chamada da função useRef
const componentRef = useRef<HTMLDivElement>(null);
isso garante que componentRef =
HTMLDivElement | null
que é o que a prop ref está esperando em vez deHTMLDivElement | undefined
.