Selecting Form Values Example

There may be times when, in your form component, you would like to have access to the values of some of the fields in your form. To get them, you will need to connect() directly to the form values in the Redux store. To facilitate this common use case, redux-form provides a convenient selector via the formValueSelector API.

WARNING: Use this method sparingly, as it will cause your entire form to re-render every time one of the values you are selecting changes.

Running this example locally

To run this example locally on your machine clone the redux-form repository, then cd redux-form to change to the repo directory, and run npm install.

Then run npm run example:selectingFormValues or manually run the following commands:

cd ./examples/selectingFormValues
npm install
npm start

Then open localhost:3030 in your browser to view the example running locally on your machine.

Usage

The selector is used in two steps, because the first step will generally apply to all the further usages.

First you create a selector by giving your form name:

const selector = formValueSelector('myFormName')

This will create a function that will get any value from that form from the global Redux state. Then you can either request a single value from the global state, with

const value = selector(state, 'fieldName')

OR, you may select multiple values, by passing additional field names.

const values = selector(state, 'street', 'city', 'postalCode')

which would give you an object, like:

{
  street: '1600 Pennsylvania Avenue',
  city: 'Washington, D.C.',
  postalCode: '20500'
}

Form

Values

undefined

Code

SelectingFormValuesForm.js

import React from 'react'
import { connect } from 'react-redux'
import { Field, reduxForm, formValueSelector } from 'redux-form'

let SelectingFormValuesForm = props => {
  const {
    favoriteColorValue,
    fullName,
    handleSubmit,
    hasEmailValue,
    pristine,
    reset,
    submitting
  } = props
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>First Name</label>
        <div>
          <Field
            name="firstName"
            component="input"
            type="text"
            placeholder="First Name"
          />
        </div>
      </div>
      <div>
        <label>Last Name</label>
        <div>
          <Field
            name="lastName"
            component="input"
            type="text"
            placeholder="Last Name"
          />
        </div>
      </div>
      <div>
        <label htmlFor="hasEmail">Has Email?</label>
        <div>
          <Field
            name="hasEmail"
            id="hasEmail"
            component="input"
            type="checkbox"
          />
        </div>
      </div>
      {hasEmailValue && (
        <div>
          <label>Email</label>
          <div>
            <Field
              name="email"
              component="input"
              type="email"
              placeholder="Email"
            />
          </div>
        </div>
      )}
      <div>
        <label>Favorite Color</label>
        <div>
          <Field name="favoriteColor" component="select">
            <option />
            <option value="#ff0000">Red</option>
            <option value="#00ff00">Green</option>
            <option value="#0000ff">Blue</option>
          </Field>
        </div>
      </div>
      {favoriteColorValue && (
        <div
          style={{
            height: 80,
            width: 200,
            margin: '10px auto',
            backgroundColor: favoriteColorValue
          }}
        />
      )}
      <div>
        <button type="submit" disabled={pristine || submitting}>
          Submit {fullName}
        </button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>
          Clear Values
        </button>
      </div>
    </form>
  )
}

// The order of the decoration does not matter.

// Decorate with redux-form
SelectingFormValuesForm = reduxForm({
  form: 'selectingFormValues' // a unique identifier for this form
})(SelectingFormValuesForm)

// Decorate with connect to read form values
const selector = formValueSelector('selectingFormValues') // <-- same as form name
SelectingFormValuesForm = connect(state => {
  // can select values individually
  const hasEmailValue = selector(state, 'hasEmail')
  const favoriteColorValue = selector(state, 'favoriteColor')
  // or together as a group
  const { firstName, lastName } = selector(state, 'firstName', 'lastName')
  return {
    hasEmailValue,
    favoriteColorValue,
    fullName: `${firstName || ''} ${lastName || ''}`
  }
})(SelectingFormValuesForm)

export default SelectingFormValuesForm