React Hook Formの使い方

## React Hook formとは
入力フォームの管理ができるライブラリです。バリデーションを実装することも出来ます。

## 実装例

実装例としては以下になります。

```
import React, { useState } from "react"
import { Text, View } from "react-native"
import { useForm, Controller } from "react-hook-form"

const App = ({ navigation }) => {

  const {
    control,
    handleSubmit,
    formState: { errors, isValid },
  } = useForm({ mode: "onChange" })

  const onSubmit = async (data) => {
    await axiosInstance.post("/register/tmp", data)
    navigation.navigate("")
  }
  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === "ios" ? "padding" : "height"}
      keyboardVerticalOffset={headerHeight - 20}
    >
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View>
          <View>
              <Text>メールアドレス</Text>
                <Controller
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　control={control}
                  rules={{
                    required: true,
                    pattern: /^[a-zA-Z0-9_+-]+(.[a-zA-Z0-9_+-]+)*@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$/,
                  }}
                  render={({ field: { onChange, onBlur, value } }) => (
                    <InputFormEmail
                      onBlur={onBlur}
                      onChangeText={onChange}
                      value={value}
                      maxLength={190}
                    />
                  )}
                  name="email"
                  defaultValue=""
                />
                {errors.email && errors.email.type === "required" && (
                  <Text>入力必須です</Text>
                )}
                 {errors.email &&
                errors.email.type === "pattern" && (
                  <Text>
                    入力形式が正しくありません
                  </Text>
                )}
              </View>
            </View>

            <View>
             <Text>パスワード</Text>
               <View>
                <Controller
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　control={control}
                  rules={{
                    required: true,
                    maxLength: 20,
                  }}
                  render={({ field: { onChange, onBlur, value } }) => (
                    <InputFormText
                      onBlur={onBlur}
                      onChangeText={onChange}
                      value={value}
                      placeholder={"6〜20文字の半角英数字"}
                      maxLength={20}
                      secureTextEntry={Eye}
                    />
                  )}
                  name="password"
                  defaultValue=""
                />
                <Pressable
                  onPress={switchPress}
                >
                  {Eye ? <View>{eyeSlash}</View> : <View>{eye}</View>}
                </Pressable>
                {errors.password && errors.password.type === "required" && (
                  <Text>入力必須です</Text>
                )}
              </View>
            </View>
          </View>

          <View>
            <ButtonGreen
              text={"次へ"}
              disabled={!isValid}
              onPress={handleSubmit(onSubmit)}
            />
          </View>
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  )
}

export default App;


```

__useForm__
引数にオブジェクトで色んな設定が可能です。
以下公式サイトの実装例↓

```
useForm({
  mode: 'onSubmit',
  reValidateMode: 'onChange',
  defaultValues: {},
  resolver: undefined,
  context: undefined,
  criteriaMode: "firstError",
  shouldFocusError: true,
  shouldUnregister: false,
  shouldUseNativeValidation: false,
  delayError: undefined
})
```
https://react-hook-form.com/api/useform/#main

よく使っているのが、mode: 'onChange'で、入力フォームに入力された内容が変更されるたびにバリデーションを実行でき、リアルタイムにエラーメッセージを表示できるのがいいなと思っています。

__Controller__
・rulesで入力必須設定をしたり、文字数の設定が出来ます。
・patternで正規表現にてバリデーションを実装出来るのですが、こちらはよく使ったりします。
・renderで実際に表示させるコンポーネントの指定を行ないます。自分で作成したものなど、フォームのコンポーネントを囲う事で簡単に実装出来ます。

## 使ってみた感想
よく公式サイトのコードをコピペして動かしてもうまく動かない事があるかと思いますが、こちらのサイトのコードはしっかり動いていました。（Version7の場合）
もしアレンジしてみたいと思ったらカスタマイズ性も高いので色々いじってみると面白いかもしれません。今後もお世話になるライブラリだと思うので、自分も色々触ってみようと思います。