React + TS + アロー関数コンポーネントでのforwardRefの書き方

  • TS の情報に乏しく無駄にハマったのでメモ程度に

確認環境

EnvVer
React17.0.1
TypeScript4.1.3

サンプルコード

  • 今回はサンプルとして <input /> をラップしたコンポーネントのフォーカスを変更するために ref を使います

Child.tsx

import { forwardRef } from 'react';
export type ChildProps = { type: 'text' | 'password' | 'number'; onChange(changeValue: string): void;
};
// function 記法でないと ESLint が怒るので無効化
// eslint-disable-next-line react/display-name
export const Child = forwardRef<HTMLInputElement, ChildProps>( // このpropsに明示的な型定義がないと型エラーが出る (props: ChildProps, ref) => { const onChange = (ev: React.ChangeEvent<HTMLInputElement>) => { props.onChange(ev.target.value); }; return ( <input ref={ref} type={props.type} onChange={(ev) => onChange(ev)} /> ); }
);

Parent.tsx

  • 下側の <Child /> だけフォーカスが行くようにしてます

import { useEffect, useRef } from 'react';
import { Child } from './Child';
export const Parent = () => { const ref = useRef<HTMLInputElement>(null); useEffect(() => { ref?.current?.focus(); }, []); return ( <ul> <li> <Child type={'text'} onChange={(ev) => console.log('top input', ev)} /> </li> <li> <Child ref={ref} type={'text'} onChange={(ev) => console.log('bottom input', ev)} /> </li> </ul> );
};