React Native + ExpoでTextInputにバリデーションをかけたくてググったところ、React-Hook-FormというReactのライブラリを発見しました。ライブラリの説明では、類似ライブラリであるFormikやRedux Formよりもシンプルに書けるとアピールされています。ドキュメントに日本語版があるのも嬉しいですね。使ってみました。
React Hook Form
高性能で柔軟かつ拡張可能な使いやすいフォームバリデーションライブラリ。
https://react-hook-form.com/jp/
インストール
$ yarn add react-hook-form
下準備
以下のようにインポートし、useFormフックで必要なAPI・オブジェクトを引っ張ってきます。FormDataにはフォームが保持する値を定義します。
import { useForm, Controller } from 'react-hook-form'
const { control, handleSubmit, errors } = useForm<FormData>()
type FormData = {
firstName: string
}
入力コントロールにバリデーションをかける
フォームの入力コントロールをControllerタグでJSX内に定義します。
<Controller
control={control}
render={({ onChange, onBlur, value }) => (
<TextInput
style={styles.input}
onBlur={onBlur}
onChangeText={value => onChange(value)}
value={value}
/>
)}
name="firstName"
rules={{ required: true }}
defaultValue=""
/>
{errors.firstName && <Text>This is required.</Text>}
renderには、画面に表示される入力コントロールのコンポーネントを指定します。propsに渡ってくるonChange, onBlur, valueを適宜処理します。
バリデーションエラーは、nameに指定した名前でerrorsオブジェクトの中に入ってきます。errors.firstNameを条件にすることで、バリデーションに失敗したときに項目ごとのエラーメッセージを表示できます。
rulesはバリデーションの内容で、required, min, max, minLength, maxLength, pattern(正規表現)などを指定できます。
defaultValueは文字通りデフォルト値です。
サブミット処理に関数をかませる
ボタン押下でhandleSubmit関数が動いて、エラーがあればerrorsオブジェクトが更新されてonSubmitは実行されない、エラーがなければonSubmitが更新される、という振る舞いになります。
<Button onPress={handleSubmit(onSubmit)} label="SAVE"></Button>