¿Cómo puedo usar una referencia de React como una instancia mutable, con Typescript? La propiedad actual parece estar escrita como de solo lectura.
Estoy usando React + Typescript para desarrollar una biblioteca que interactúa con los campos de entrada que NO son representados por React. Quiero capturar una referencia al elemento HTML y luego vincular eventos React a él.
const inputRef = useRef<HTMLInputElement>(); const { elementId, handler } = props; // Bind change handler on mount/ unmount useEffect(() => { inputRef.current = document.getElementById(elementId); if (inputRef.current === null) { throw new Exception(`Input with ID attribute ${elementId} not found`); } handler(inputRef.current.value); const callback = debounce((e) => { eventHandler(e, handler); }, 200); inputRef.current.addEventListener('keypress', callback, true); return () => { inputRef.current.removeEventListener('keypress', callback, true); }; }); Genera errores del compilador: semantic error TS2540: Cannot assign to 'current' because it is a read-only property.
También probé const inputRef = useRef<{ current: HTMLInputElement }>(); Esto conduce a este error del compilador:
Type 'HTMLElement | null' is not assignable to type '{ current: HTMLInputElement; } | undefined'. Type 'null' is not assignable to type '{ current: HTMLInputElement; } | undefined'.Sí, esta es una peculiaridad de cómo se escriben los tipos:
function useRef<T>(initialValue: T): MutableRefObject<T>; function useRef<T>(initialValue: T|null): RefObject<T>; Si el valor inicial incluye null , pero el parámetro de tipo especificado no lo incluye, se tratará como un RefObject inmutable.
Cuando useRef<HTMLInputElement>(null) , está acertando en ese caso, ya que T se especifica como HTMLInputElement y null se infiere como HTMLInputElement | null
Puedes arreglar esto haciendo:
useRef<HTMLInputElement | null>(null) Entonces T es HTMLInputElement | null , que coincide con el tipo del primer argumento, por lo que presiona la primera anulación y obtiene una referencia mutable en su lugar.
Llegué a esta pregunta buscando cómo escribir useRef con Typescript cuando se usa con setTimeout o setInterval . La respuesta aceptada me ayudó a resolver eso.
Puede declarar su tiempo de espera/intervalo así
const myTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)Y para borrarlo y configurarlo de nuevo, lo haces como siempre:
const handleChange = () => { if (myTimeout.current) { clearTimeout(myTimeout.current) } myTimeout.current = setTimeout(() => { doSomething() }, 500) }La escritura funcionará tanto si está ejecutando en un nodo como en un navegador.