LoginSignup
12
9

More than 5 years have passed since last update.

Formik(というかYup)でemailがユニークかどうかとかpasswordが一致するかなどを検証する

Last updated at Posted at 2018-11-25

前提

ReactNativeでの話です。あと、この記事の続き的なものです。Formikの基本的な動作はそちらを御覧ください。

やりたいこと

  • emailが既に登録されていないか検証
  • passwordとpasswordConfirm(確認用)が一致するかどうか検証

下記のような感じ。

スクリーンショット 2018-11-25 7.06.25.png

やりかた

emailが既に存在するかどうか

.test()を利用してみます。.test()はカスタムバリデーションの実装に利用できる関数で、

.test([テスト名],[エラーメッセージ],[関数])

という形式で、引数で与えられたvalueを検証し、true, falseを返すことでカスタムバリデーションを実装できるようです。

passwordが一致するかどうか

Yupでは、

.oneOf()

という形式で他の値を参照できるので利用してみます。

実装

App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Formik, yupToFormErrors } from 'formik';
import { Card, Button, FormLabel, FormInput, FormValidationMessage } from 'react-native-elements';
import * as Yup from 'yup';

export default class App extends React.Component {
  render() {
    return (
      <View style={{ paddingVertical: 60 }}>
        <Formik
          initialValues={{
            name: '',
            email: '',
            password: '',
            passwordConfirm: ''
          }}
          onSubmit={values => this._handleSubmit(values)}
          validationSchema={Yup.object().shape({
            name: Yup
              .string()
              .required('名前は必須です。'),
            email: Yup
              .string()
              .email('形式がemailではありません。')
              .required('emailは必須です。')
+             .test('email-test', '既に存在します。', (value) => {
+               if (value === 'test@test.com') {
+                 return false;
+               } else {
+                 return true;
+               }
+             }),
            password: Yup
              .string()
              .min(4, 'パスワードは最低4文字です。')
              .required('passwordは必須です。'),
            passwordConfirm: Yup
              .string()
+             .oneOf([Yup.ref('password')], 'passwordが一致しません。')
              .required('passwordは必須です。'),
          })}
        >
          {
            ({ handleChange, handleSubmit, values, errors }) => (
              <Card title='登録フォーム'>
                <FormLabel>Name</FormLabel>
                <FormInput
                  autoCapitalize='none'
                  onChangeText={handleChange('name')}
                  value={values.name}
                />
                <FormValidationMessage>{errors.name}</FormValidationMessage>

                <FormLabel>Email</FormLabel>
                <FormInput
                  autoCapitalize='none'
                  onChangeText={handleChange('email')}
                  value={values.email}
                />
                <FormValidationMessage>{errors.email}</FormValidationMessage>

                <FormLabel>Password</FormLabel>
                <FormInput
                  autoCapitalize='none'
                  onChangeText={handleChange('password')}
                  value={values.password}
                  secureTextEntry
                />
                <FormValidationMessage>{errors.password}</FormValidationMessage>

                <FormLabel>PasswordConfirm</FormLabel>
                <FormInput
                  autoCapitalize='none'
                  onChangeText={handleChange('passwordConfirm')}
                  value={values.passwordConfirm}
                  secureTextEntry
                />
                <FormValidationMessage>{errors.passwordConfirm}</FormValidationMessage>

                <Button
                  title="登録"
                  onPress={handleSubmit}
                  buttonStyle={{ marginTop: 20 }}
                />
              </Card>
            )
          }
        </Formik>
      </View>
    );
  }

  _handleSubmit = (values) => {
    alert(JSON.stringify(values));
  }
}

上記では、emailは単にtest@test.comに一致するかどうかで検証していますが、実際にはaxios等でAPIを照会することになります。

12
9
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
12
9