7.0.0アップデート
React Hook Form 7.0.0へアップデートしたということで、v6.15.1からアップデートしたことで、変更が必要だった点をアウトプット
注意:すべてはmigration guideに書かれている!!
今回の修正コード
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"
/>
{}
の中で続けて書けば良いって言うだけですね
最後に
以上がアップデートによるマイグレーションでした。
今回は小さめのフォームであったためそこまで大きな変更はなかったのですが、他にも変更箇所はありますので確認した上でアップデートは行っていきましょう。