20
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

redux-formでFieldレベルのvalidateをやり方と気をつけること

Posted at

環境

  • react ^16.3.2
  • react-redux ^5.0.7
  • redux ^4.0.0
  • redux-form ^7.3.0

FieldレベルでValidate

Redux Form - Synchronous Validation ExampleここでやっているようなValidateの方法もありますが、これだと汎用性に欠けるので僕は専らFieldレベルでValidateするようにしています。

component

FieldレベルでのValidateを実装する場合にはFieldにvalidateプロパティを渡すだけです。んで、配列になっているのでいくつもValidateメソッドを渡すことができます。
下記の場合であれば必須チェックとメールアドレスチェックですね。

import { Field, reduxForm } from 'redux-form'
import * as Validator from 'utils/validate'

const MyComponet = () => {
  {/** 省略 **/}
}

render() {
  return(
  <Field
    component={MyComponent}
    name="email"
    type="email"
    floatingLabel="ユーザー名"
    textSize={16}
    icon={['fas', 'fa-envelope']}
    validate={[Validator.email, Validator.required]}
  />
  )
}

Validate.js

utils/Validate.jsとかで別ファイルで作って置くといいですね。
やってることは簡単で正規表現でチェックしてメッセージを出すかundefinedreturnします。

extendValidatorについてはちょっと説明が必要なので後述しますね。

const ErrorMessages = {
  required: '必須項目です。',
  email: '正しいメールアドレスの形式でご入力ください。',
  password: '英字、数字を組み合わせた8文字以上16文字以内で入力。',
  url: 'URLの形式が間違っています。 例:https://example.com'
}

const Regex = {
  email: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
  password: /^(?=.*?[a-zA-Z])(?=.*?\d)[!-\~]{8,16}$/,
  url: /^(https?)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$/
}

export const required = value => (value || typeof value === 'number' ? undefined : ErrorMessages.required)

export const email = value => (value && !Regex.email.test(value) ? ErrorMessages.email : undefined)

export const password = value => (value && !Regex.password.test(value) ? ErrorMessages.password : undefined)

export const url = value => (value && !Regex.url.test(value) ? ErrorMessages.url : undefined)

export const extendValidator = text => func => (func ? text : undefined)

extendValidator

validateメソッドを拡張するメソッドです。なんで拡張する理由があるかというとエラーメッセージを変えたいなどに対応するためです。例えば・・・

ログインページでは必須チェックのメッセージを「必須項目です」ではなく「ログイン用のメールアドレスが入力されていません」といった感じで局所的に変更を加えたい場合などですね。

使い方

const exEmail = value => Validator.extendValidator('ちげーし')(Validator.email(value))

validate={[Validator.exEmail]}

とは言ってもこれでは拡張メソッドを新たに作る必要はないですよね。validateメソッドに引数で文言を渡せばいいじゃんとなりますもんね。実はredux-formのバージョンが新しくなって例えばrequired('ほげ')とvalidateに渡すことができなくなってしまったんです。なのでどうするかというと拡張メソッドを作るか、下記のような感じでもできます。

export const email = text => value => {
  if (value && !Regex.email.test(value)) {
    return text ? text : ErrorMessages.email
  }
  return undefined
}

validate={[(value) => Validator.email('違うし')(value)]}

ちなみにvalidateでは(value, values, props)を受け取ることができます。なので、パスワード確認とかも簡単にできます。

<Field
  component={FieldInput}
  name="password"
  type="password"
  validate={[Validator.password, Validator.required]}
  classes={['u-mb-24']}
/>
<Field
  component={FieldInput}
  name="confirm"
  type="password"
  validate={[(value, values) => (
      Validator.confirmPass(value)(values.password)
    ), Validator.required]}
/>
export const confirmPass = value => pass => {
  if (value !== pass) {
    return 'パスワードが違います'
  }
  return undefined
}
20
12
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
20
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?