kk-web

【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 で受け取るコンポーネントを書くことってあまり多くないので、つい書き方を忘れがちですよね。

© 2018 kk-web