Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

React Redux Form v0.7.0

Compare
Choose a tag to compare
@davidkpiano davidkpiano released this 01 Mar 03:35
· 1449 commits to master since this release

The <Form> Component

React Redux Form 0.7.0 introduces the <Form> component, which will allow you to provide form-wide (and per-field) validation on submit, and/or on field changes.

  • <Form validators={{...}}> lets you specify validators for each field in the model, or for the form itself
  • <Form validateOn="change"> will execute the validators on every change of its model, and will only validate fields that have been changed.
  • <Form onSubmit={...}> works like the standard onSubmit prop, with these two changes:
    • Event bubbling is prevented by default (e.preventDefault()) so the form doesn't auto-submit
    • The onSubmit function will not be called if the form is invalid.

Here's an example of <Form> in action:

import { Form, Field } from 'react-redux-form';
import validator from 'validator'; // Use any validation library!

// an action thunk creator
function customSubmitUser(user) {
  return (dispatch) => {
    // do any async submitting stuff here
  }
}

// inside component render():
<Form model="user"
  onSubmit={ customSubmitUser }
  validators={{
    // form validation
    '': {
      passwordsMatch: (user) => user.password === user.confirmPassword
    },

    // field validation
    'email': {
      valid: validator.isEmail,
      required: (email) => email && email.length
    },
    'password': (pass) => pass && pass.length > 8
  }}
>
  <Field model="user.email">
    <input type="email" />
  </Field>

  <Field model="user.password">
    <input type="password" />
  </Field>

  <Field model="user.confirmPassword">
    <input type="password" />
  </Field>
</Form>

Custom Error Messages

Now, RRF will let you set custom error messages using actions.setErrors(model, errors):

import { actions, getField } from 'react-redux-form';

// in a connected component's render() method:
dispatch(actions.setErrors('user.email', 'Invalid email!'));

getField(userForm, 'email').errors;
// => 'Invalid email!'

getField(userForm, 'email').valid;
// => false

// objects and arrays, etc. can be errors, too!
dispatch(actions.setErrors('user.email', {
  validEmail: 'This does not look like a valid email',
  availability: 'Also this email is taken'
});

getField(userForm, 'email').errors;
// => { validEmail: 'This...', availability: 'Also, this...' } (truncated)

getField(userForm, 'email').validity;
// => { validEmail: false, availability: false }

getField(userForm, 'email').valid;
// => false

Submit via Promises with actions.submit()

The actions.submit(model, promise) action is especially useful when you have custom error messages coming from the API:

function submitUser(user) {
  return fetch(...).then(...); // sample promise
}

// somewhere with dispatch()
dispatch(actions.submit('user', submitUser(user)));

This will:

  1. Set the form's .pending state to true
  2. Then it'll wait for the promise to resolve.
  3. Once the promise resolves, .pending will be set to false
  • If the promise is rejected, the .errors state of the form will be set to the rejection value.
  • If the promise is fulfilled, the .submitted state will be set to true.

Major Clean-Up

Thanks to the huge amount of help from @chrisblossom, the RRF project was significantly cleaned up and the build optimized for size (which is an ongoing task). RRF now uses ESLint and makes use of peerDependencies.