0
2

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 (4) - Submit Validation Example

Last updated at Posted at 2019-07-03

redux-form (1) - Simple Form Example
redux-form (2) - Synchronous Validation Example
redux-form (3) - Field-Level Validation Example
redux-form (4) - Submit Validation Example
redux-form (5) - Initialize From State
redux-form (6) - ユーザ登録


ReactでForm componentを作るときに、とても便利な**redux-form**の説明です。

redux-formの概説についてはまず以下の記事を参考にしてください。

redux-form (1) - Simple Form Example

Submit Validation Example

Submit Validation Example - Getting Started With redux-form

今回は、Submit時のエラー処理についてです。

今回はonSubmitがpropとして指定されていないので、以下のonSubmit関数(submit)をhandleSubmit()の引数として与えます。

src/submit.js
import { SubmissionError } from 'redux-form'

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

function submit(values) {
  return sleep(1000).then(() => {
    // simulate server latency
    if (!['john', 'paul', 'george', 'ringo'].includes(values.username)) {
      throw new SubmissionError({
        username: 'User does not exist', // 個別のfieldエラー
        _error: 'Login failed!'          // form全体のエラー
      })
    } else if (values.password !== 'redux-form') {
      throw new SubmissionError({
        password: 'Wrong password', // 個別のfieldエラー
        _error: 'Login failed!'     // form全体のエラー
      })
    } else {
      window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`)
    }
  })
}

export default submit

ここで注目すべきは以下のコードです。submit関数がpromiseで、rejectで new SubmissionError({ field1: 'error', field2: 'error' }) というエラーを投げれば、それぞれのfield (field1, field2)にエラーが追加されます。下のコードではusernameのfieldにエラーが追加されます。_error は個別のfieldでなく、form全体のエラーを表示したいときに追加します。

      throw new SubmissionError({
        username: 'User does not exist', // 個別のfieldエラー
        _error: 'Login failed!'          // form全体のエラー
      })

wrapped componentは以下のようになっています。this.props.onSubmitは渡されてきていないので、直接submit関数をimportし、handleSubmitの引数にしています。

src/SubmitValidationForm.js
import React from 'react'
import { Field, reduxForm } from 'redux-form'
import submit from './submit'

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} placeholder={label} type={type} />
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const SubmitValidationForm = props => {
  const { error, handleSubmit, pristine, reset, submitting } = props
  return (
    // onSubmitがpropとして渡ってきていないので引数として与える
    <form onSubmit={handleSubmit(submit)}>
      <Field
        name="username"
        type="text"
        component={renderField}
        label="Username"
      />
      <Field
        name="password"
        type="password"
        component={renderField}
        label="Password"
      />
      {error && <strong>{error}</strong>}
      <div>
        <button type="submit" disabled={submitting}>
          Log In
        </button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>
          Clear Values
        </button>
      </div>
    </form>
  )
}

export default reduxForm({
  form: 'submitValidation' // a unique identifier for this form
})(SubmitValidationForm)

index.jsはオリジナルを変えて最小限のものに修正してあります。

src/index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { createStore, combineReducers } from 'redux'
import { reducer as reduxFormReducer } from 'redux-form'

const dest = document.getElementById('content')
const reducer = combineReducers({
  form: reduxFormReducer // mounted under "form"
})
const store = createStore(reducer)

let render = () => {
  const SubmitValidationForm = require('./SubmitValidationForm').default
  ReactDOM.hydrate(
    <Provider store={store}>
        <h2>Form</h2>
        <SubmitValidationForm />
    </Provider>,
    dest
  )
}

render()

実行結果

submitボタンをクリックしたときの画面です。

passwordエラー時の画面です。password field 個別のエラー 'Wrong password'が表示されています。加えてform全体のエラー 'Login failed!' が表示されています。
image.png

エラーなしで、成功時の画面です。
image.png

今回は以上です。

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?