如何使用 Typescript 将 React ref 用作可变实例?当前属性似乎类型为只读。
我正在使用 React + Typescript 开发一个库,该库与 React 未呈现的输入字段交互。我想捕获对 HTML 元素的引用,然后将 React 事件绑定到它。
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);
};
});
它生成编译器错误:semantic error TS2540: Cannot assign to 'current' because it is a read-only property.
我也尝试const inputRef = useRef<{ current: HTMLInputElement }>();
这会导致此编译器错误:
Type 'HTMLElement | null' is not assignable to type '{ current: HTMLInputElement; } | undefined'.
Type 'null' is not assignable to type '{ current: HTMLInputElement; } | undefined'.
是的,这是打字的怪癖:
function useRef<T>(initialValue: T): MutableRefObject<T>;
function useRef<T>(initialValue: T|null): RefObject<T>;
如果初始值包含null
,但指定的类型参数不包含,则会将其视为不可变RefObject
。
当你做useRef<HTMLInputElement>(null)
时,你遇到了这种情况,因为T
被指定为HTMLInputElement
,而null
被推断为HTMLInputElement | null
。
您可以通过执行以下操作来解决此问题:
useRef<HTMLInputElement | null>(null)
然后T
是HTMLInputElement | null
,它与第一个参数的类型匹配,因此您点击第一个覆盖并得到一个可变的 ref。
as
键。
您可以像这样将其用于输入组件。
const inputRef = useRef() as MutableRefObject<HTMLInputElement>;
我通过搜索如何在与setTimeout
或setInterval
一起使用时使用 Typescript 键入useRef
来解决这个问题。被接受的答案帮助我解决了这个问题。
您可以像这样声明超时/间隔
const myTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)
要清除它并再次设置它,您可以像往常一样进行操作:
const handleChange = () => {
if (myTimeout.current) {
clearTimeout(myTimeout.current)
}
myTimeout.current = setTimeout(() => {
doSomething()
}, 500)
}
如果您在 Node 或浏览器中运行,则键入将起作用。
你必须编写这样的代码:
const inputRef = useRef<HTMLInputElement>(null);
当你需要使用它时,你必须这样写:
inputRef.current?.focus();