1. ホーム
  2. reactjs

[解決済み] useRef()フックで電流を手動で設定する場合、どのようなtypescriptタイプを使用すればよいですか?

2022-12-14 17:20:01

質問

React の ref を mutable なインスタンスとして、Typescript で使用するにはどうしたらよいでしょうか。現在のプロパティは読み取り専用として型付けされているように見えます。

私は 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) とすると、そのケースに当たるので THTMLInputElement であり、かつ null と推論されます。 HTMLInputElement | null .

とすることで修正できます。

useRef<HTMLInputElement | null>(null)

次に THTMLInputElement | null であり、これは最初の引数の型にマッチします。したがって、最初のオーバーライドをヒットし、代わりにミュータブルリフレクションを取得します。