【TypeScript】Input コンポーネントに ref を渡す方法
2021-04-16
ref って便利ですが、型周りは結構やっかいですよね。
ということで、ざくっと書いてみました。
React Hook Form の v7 を使う場合のコードですが、ref 周りはすべてのケースで共通だと思います。
import React, { FC, forwardRef, Ref } from "react";
import { ChangeHandler } from "react-hook-form";
export type InputProps = {
name: string;
onBlur: ChangeHandler;
onChange: ChangeHandler;
ref: Ref<HTMLInputElement>;
};
const Input: FC<InputProps> = forwardRef<
HTMLInputElement,
Omit<InputProps, "ref">
>(({ name, onBlur, onChange, type }: Omit<InputProps, "ref">, ref) => (
<input
className={styles.input}
name={name}
onBlur={onBlur}
onChange={onChange}
ref={ref}
type={type}
/>
));
Input.displayName = "Input";
export default Input;
displayName
は eslint のためなので、省いても動くと思います。
呼び出す側は何も気にせず ref を渡して、呼び出される側は丁寧に ref を受け取りましょう、という感じですかね?
React Hook Form からの呼び出しは公式サイト通りで問題ないです。
import React, { FC } from "react";
import { useForm } from "react-hook-form";
import Input from "components/atoms/Input";
type FieldValues = Record<"hoge", string>;
export type FormProps = {
onSubmit: (values: FieldValues) => void;
};
const Form: FC<FormProps> = ({ onSubmit }: FormProps) => {
const { register, handleSubmit } = useForm<FieldValues>();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Input {...register("hoge")} />
<button type="submit">送信</button>
</form>
);
};
export default Form;
ref を props で受け取るコンポーネントを書くことってあまり多くないので、つい書き方を忘れがちですよね。