Initialize From State

Values provided to the initialValues prop or reduxForm() config parameter will be loaded into the form state and treated thereafter as "pristine". They will also be the values that will be returned to when reset() is dispatched. In addition to saving the "pristine" values, initializing your form will overwrite any existing values.

In many applications, these values will be coming from the server and stored in another Redux reducer. To get those values into your redux-form-decorated component, you will need to connect() to the Redux state yourself and map from the data reducer to the initialValues prop.

By default, you may only initialize a form component once via initialValues. There are two methods to reinitialize the form component with new "pristine" values:

  1. Pass a enableReinitialize prop or reduxForm() config parameter set to true to allow the form the reinitialize with new "pristine" values every time the initialValues prop changes. To keep dirty form values when it reinitializes, you can set keepDirtyOnReinitialize to true. By default, reinitializing the form replaces all dirty values with "pristine" values.

  2. Dispatch the INITIALIZE action (using the action creator provided by redux-form).

The following example references an external account reducer, which simply takes an object of values and saves it in the store under account.data when you dispatch the load action by clicking the "Load Account" button.

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:initializeFromState or manually run the following commands:

cd ./examples/initializeFromState
npm install
npm start

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

Form

Values

undefined

Code

account.js

// Quack! This is a duck. https://github.com/erikras/ducks-modular-redux
const LOAD = 'redux-form-examples/account/LOAD'

const reducer = (state = {}, action) => {
  switch (action.type) {
    case LOAD:
      return {
        data: action.data
      }
    default:
      return state
  }
}

/**
 * Simulates data loaded into this reducer from somewhere
 */
export const load = data => ({ type: LOAD, data })

export default reducer

InitializeFromStateForm.js

import React from 'react'
import { connect } from 'react-redux'
import { Field, reduxForm } from 'redux-form'
import { load as loadAccount } from './account'
const data = {  // used to populate "account" reducer when "Load" is clicked
  firstName: 'Jane',
  lastName: 'Doe',
  age: '42',
  sex: 'female',
  employed: true,
  favoriteColor: 'Blue',
  bio: 'Born to write amazing Redux code.'
}
const colors = [ 'Red', 'Orange', 'Yellow', 'Green', 'Blue', 'Indigo', 'Violet' ]

let InitializeFromStateForm = props => {
  const { handleSubmit, load, pristine, reset, submitting } = props
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <button type="button" onClick={() => load(data)}>Load Account</button>
      </div>
      <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>Age</label>
        <div>
          <Field name="age" component="input" type="number" placeholder="Age"/>
        </div>
      </div>
      <div>
        <label>Sex</label>
        <div>
          <label><Field name="sex" component="input" type="radio" value="male"/> Male</label>
          <label><Field name="sex" component="input" type="radio" value="female"/> Female</label>
        </div>
      </div>
      <div>
        <label>Favorite Color</label>
        <div>
          <Field name="favoriteColor" component="select">
            <option value="">Select a color...</option>
            {colors.map(colorOption =>
              <option value={colorOption} key={colorOption}>{colorOption}</option>)}
          </Field>
        </div>
      </div>
      <div>
        <label htmlFor="employed">Employed</label>
        <div>
          <Field name="employed" id="employed" component="input" type="checkbox"/>
        </div>
      </div>
      <div>
        <label>Bio</label>
        <div>
          <Field name="bio" component="textarea"/>
        </div>
      </div>
      <div>
        <button type="submit" disabled={pristine || submitting}>Submit</button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>Undo Changes</button>
      </div>
    </form>
  )
}

// Decorate with reduxForm(). It will read the initialValues prop provided by connect()
InitializeFromStateForm = reduxForm({
  form: 'initializeFromState'  // a unique identifier for this form
})(InitializeFromStateForm)

// You have to connect() to any reducers that you wish to connect to yourself
InitializeFromStateForm = connect(
  state => ({
    initialValues: state.account.data // pull initial values from account reducer
  }),
  { load: loadAccount }               // bind account loading action creator
)(InitializeFromStateForm)

export default InitializeFromStateForm