手动设置当前电流时,useRef()挂钩应使用哪种打字稿类型?

时间:2019-09-19 18:40:58

标签: reactjs typescript react-hooks

如何使用带有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'.

1 个答案:

答案 0 :(得分:9)

是的,这是有关打字方式的古怪之处:<​​/ p>

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。 / p>

您可以通过以下方法解决此问题:

useRef<HTMLInputElement | null>(null)

然后THTMLInputElement | null,它与第一个参数的类型匹配,因此您点击了第一个替代并获得了可变的引用。