LoginSignup
27
16

More than 3 years have passed since last update.

React Hook Form 7.0.0アップデートにあたってマイグレーションを行う

Posted at

7.0.0アップデート

React Hook Form 7.0.0へアップデートしたということで、v6.15.1からアップデートしたことで、変更が必要だった点をアウトプット
注意:すべてはmigration guideに書かれている!!

今回の修正コード

login.tsx
import { useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { jsx } from '@emotion/react';
import { useForm } from "react-hook-form";

import {
  fetchAsyncLogin,
  selectUser
} from '../../../stores/slices/userSlice'
import { BrowserRouter as Router, useHistory } from 'react-router-dom'
import { hot } from 'react-hot-loader'

import Header from '../../components/block/Header'
import Footer from '../../components/block/Footer'

import { LoginTitle } from '../../../style/pages/Login'

interface loginFormInput {
  userName: string;
  passWord: string;
}

const Login = () => {
  // 一時的な保持は各コンポーネントで行う
  const { register, handleSubmit, errors, reset } = useForm<loginFormInput>();
  const dispatch = useDispatch()
  const history = useHistory()

  //   storeに保存されている情報を変数にいれる
  const user = useSelector(selectUser)


  const onSubmit = (data: loginFormInput) => {
    dispatch(fetchAsyncLogin(data))
    reset()
    if (user.isLogin === true) {
      history.push('/top')
    }
  }

  //   Loginを検知してページ遷移
  useEffect(() => {
    console.log(user)
    if (user.isLogin === true) {
      history.push('/top')
    }
  }, [user.isLogin])

  return (
    <div>
      <Header />
      <h1 css={LoginTitle}>Login Page</h1>
      {errors.userName && '入力に不備がございます'}
      <form onSubmit={handleSubmit(onSubmit)}>
        <input
          type="text"
          name="userName"
          aria-invalid={errors.userName ? "true" : "false"}
          ref={register({ required: true })}
          placeholder="user"
        />
        {errors.userName && errors.userName.type === "required" && <span role="alert">必須だよ!</span>}
        <input
          type="text"
          name="passWord"
          aria-invalid={errors.passWord ? "true" : "false"}
          ref={register({ required: true, pattern: /^[A-Za-z]+$/i })}
          placeholder="pass"
        />
        {errors.passWord && errors.passWord.type === "required" && <span role="alert">必須だよ!</span>}
        {errors.passWord && errors.passWord.type === "pattern" && <span role="alert">半角英数字でお願いします!</span>}
        <input type="submit" />
      </form>
      <Footer />
    </div>
  )
}

export default hot(module)(Login)

プロパティ 'errors' は型 'UseFormReturn' に存在しません。

下記コードで7へアップデートするとタイトルの注意が出てくる。

const { register, handleSubmit, errors, reset } = useForm<loginFormInput>();

migration guideをみてみる。

errors:
errors object has been moved into formState object. This will info hook form that errors object is been subscribed.

なるほど
errosオブジェクトはformStateの中へ移動したと多分書かれています。

- const { register, handleSubmit, errors, reset } = useForm<loginFormInput>();

+ const { register, handleSubmit, formState: { errors }, reset } = useForm<loginFormInput>();

これで注意は消えます。

FormRegisterReturn' を型 'LegacyRef | undefined' に割り当てることはできません。プロパティ 'current' は型 'UseFormRegisterReturn' にありませんが、型 'RefObject' では必須です。

以下のコードだとタイトルのような注意が出る。

 <input
  type="text"
  name="userName"
  aria-invalid={errors.userName ? "true" : "false"}
  ref={register({ required: true })}
  placeholder="user"
/>

migration guideをみてみる。

register method is no longer occurred at ref, instead invoke the function itself and spread the props into the input. The function itself will return the following props: onChange, onBlur, name and ref.

refの中でregisterは呼び出せなくなったぞ!ただregister関数を呼び出し、そこから色々設定できるぞい的なことが書かれているぽい

<input
  type="text"
- name="userName"
  aria-invalid={errors.userName ? "true" : "false"}
- ref={register({ required: true })}
+ {...register("userName", { required: true })}
  placeholder="user"
/>

registerの中にname属性が指定できるようになり、name属性の指定がいらなくなりました。
第二引数にrequired trueを付与することで、同じ挙動を再現できます。

今回このような形になったのは以下の理由があるそうです。

register 関数を呼び出すことで型チェックができるようになりました。元のAPIには賛否両論ありますし、型安全性と相性が悪いのは間違いありません。この変更によって、 useController, Controller などのAPIでも型チェックも行ってくれるようになります。(引用: React Hook Formのアップデート内容 - Version 7)

別のinputでバリデーションパターンを設定している箇所があります。こちらも直します。

<input
 type="text"
 name="passWord"
 aria-invalid={errors.passWord ? "true" : "false"}
 ref={register({ required: true, pattern: /^[A-Za-z]+$/i })}
 placeholder="pass"
/>
<input
  type="text"
- name="passWord"
  aria-invalid={errors.passWord ? "true" : "false"}
- ref={register({ required: true, pattern: /^[A-Za-z]+$/i })}
+ {...register("passWord", { required: true, pattern: /^[A-Za-z]+$/i })}
  placeholder="pass"
/>

{}の中で続けて書けば良いって言うだけですね

最後に

以上がアップデートによるマイグレーションでした。
今回は小さめのフォームであったためそこまで大きな変更はなかったのですが、他にも変更箇所はありますので確認した上でアップデートは行っていきましょう。

参考文献

27
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
16