← Back to erikras/redux-form

How to Deploy & Use erikras/redux-form

# Redux Form Deployment & Usage Guide

A complete guide to installing, configuring, and deploying applications using `redux-form`—a Higher Order Component library for managing form state in Redux.

> **⚠️ Important Notice**: The Redux Form author recommends [React Final Form](https://github.com/final-form/react-final-form) for new projects. Only use Redux Form if you require tight coupling between form data and Redux state across distant components or routes.

---

## 1. Prerequisites

### Runtime Requirements
- **Node.js**: v10.0.0 or higher (LTS recommended)
- **npm**: v6.0.0+ or **Yarn**: v1.22.0+
- **React**: v16.8.0+ (peer dependency)
- **Redux**: v4.0.0+ (peer dependency)
- **React-Redux**: v6.0.0+ or v7.0.0+ (peer dependency)

### Knowledge Prerequisites
- Familiarity with React component lifecycle and Hooks
- Understanding of Redux store architecture, reducers, and actions
- ES6+ syntax (arrow functions, destructuring, spread operators)

### For Library Contributors
- **Flow**: Static type checking (used throughout source in `src/*.js`)
- **Git**: For cloning repository

---

## 2. Installation

### In an Existing React/Redux Application

```bash
# Install redux-form
npm install --save redux-form

# Install required peer dependencies (if not present)
npm install --save react react-dom redux react-redux

# Optional: Install ImmutableJS support (if using immutable data)
npm install --save immutable

For Library Development/Contribution

# Clone the repository
git clone https://github.com/redux-form/redux-form.git
cd redux-form

# Install dependencies
npm install

# Verify installation
npm test

Verify Installation

Check your package.json dependencies:

{
  "dependencies": {
    "redux-form": "^8.3.0",
    "react": "^16.8.0",
    "react-dom": "^16.8.0",
    "redux": "^4.0.0",
    "react-redux": "^7.0.0"
  }
}

3. Configuration

Step 1: Add Reducer to Redux Store

Redux Form requires a specific reducer to handle form state. The source (src/createReducer.js) shows it manages actions like CHANGE, BLUR, ARRAY_PUSH, etc.

store.js:

import { createStore, combineReducers } from 'redux'
import { reducer as formReducer } from 'redux-form'

const rootReducer = combineReducers({
  // ... your other reducers
  form: formReducer  // Required: must be mounted under 'form' key
})

const store = createStore(rootReducer)
export default store

Step 2: Wrap Your Form Component

Using the Higher Order Component from src/createReduxForm.js:

MyForm.js:

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

const MyForm = ({ handleSubmit }) => (
  <form onSubmit={handleSubmit}>
    <div>
      <label htmlFor="username">Username</label>
      <Field name="username" component="input" type="text" />
    </div>
    <div>
      <label htmlFor="email">Email</label>
      <Field name="email" component="input" type="email" />
    </div>
    <button type="submit">Submit</button>
  </form>
)

// Configuration options (see src/createReduxForm.js for full API)
export default reduxForm({
  form: 'myForm',           // Unique identifier for this form
  initialValues: {          // Optional default values
    username: '',
    email: ''
  },
  onSubmit: (values) => {  // Submission handler
    console.log('Form values:', values)
  }
})(MyForm)

Step 3: Connect to Redux (Optional)

If you need to access form state from other components using selectors from src/selectors/:

import { connect } from 'react-redux'
import { getFormValues, isValid, isSubmitting } from 'redux-form'

const mapStateToProps = (state) => ({
  formValues: getFormValues('myForm')(state),
  isFormValid: isValid('myForm')(state),
  isSubmitting: isSubmitting('myForm')(state)
})

export default connect(mapStateToProps)(MyComponent)

Advanced Configuration Options

Based on src/createReduxForm.js, available config props include:

OptionTypeDescription
formStringRequired. Unique form identifier
validateFunctionSynchronous validation (values) => errors
asyncValidateFunctionAsync validation (values, dispatch) => Promise
asyncBlurFieldsArrayFields triggering async validation on blur
initialValuesObjectDefault form values
destroyOnUnmountBooleanClear form data on unmount (default: true)
forceUnregisterOnUnmountBooleanUnregister fields on unmount
keepDirtyOnReinitializeBooleanPreserve dirty values when reinitializing

4. Build & Run

Development Mode

For applications using Redux Form:

# Start React development server
npm start
# or
yarn start

Production Build

# Create optimized production build
npm run build
# or
yarn build

Testing Forms

Using the test utilities (based on src/actions.js action creators):

import { change, blur, submit } from 'redux-form'

// In your tests:
store.dispatch(change('myForm', 'username', 'newValue'))
store.dispatch(blur('myForm', 'email', 'test@example.com'))
store.dispatch(submit('myForm'))

Library Development Commands

If modifying Redux Form source:

# Run test suite (Jest + Flow types)
npm test

# Build distribution files
npm run build

# Build UMD bundle
npm run build:umd

# Run type checking
npm run flow

# Lint code
npm run lint

5. Deployment

Deploying Applications Using Redux Form

Since Redux Form is a client-side library, deploy your React app using standard static hosting:

Option A: Vercel (Recommended for React)

# Install Vercel CLI
npm i -g vercel

# Deploy
vercel --prod

Option B: Netlify

# Build your app
npm run build

# Deploy build/ folder
netlify deploy --prod --dir=build

Option C: AWS S3 + CloudFront

# Sync build folder to S3 bucket
aws s3 sync build/ s3://your-bucket-name --delete

# Invalidate CloudFront cache
aws cloudfront create-invalidation --distribution-id YOUR_ID --paths "/*"

Publishing Redux Form (For Maintainers)

# Ensure tests pass
npm test

# Build all distributions
npm run build
npm run build:umd
npm run build:umd:min

# Version bump
npm version patch|minor|major

# Publish to npm
npm publish

6. Troubleshooting

Common Issues

"Could not find 'form' in state"

Cause: Missing reducer configuration
Solution: Ensure form: formReducer is in your combineReducers:

import { reducer as formReducer } from 'redux-form'
combineReducers({ form: formReducer })

"Invalid prop component supplied to Field"

Cause: Invalid component prop passed to Field component
Solution: Use string ('input', 'textarea', 'select') or React component:

// Correct
<Field name="email" component="input" />
<Field name="bio" component={CustomInput} />

Performance Issues with Large Forms

Cause: Every keystroke triggers Redux actions (CHANGE from src/actions.js)
Solutions:

  • Use shouldComponentUpdate or React.memo on custom field components
  • Debounce validation functions
  • Consider react-final-form for simpler forms (as recommended by author)

ImmutableJS Integration Issues

Cause: Structure mismatch between plain JS and Immutable
Solution: Import from immutable-specific entry:

import { Field, reduxForm } from 'redux-form/immutable'

Async Validation Not Triggering

Cause: Missing asyncBlurFields configuration
Solution: Specify which fields trigger async validation:

reduxForm({
  form: 'myForm',
  asyncValidate,
  asyncBlurFields: ['username', 'email']
})(MyForm)

Hot Reloading Loses Form State

Cause: HMR remounting components triggers DESTROY action
Solution: Set destroyOnUnmount: false during development:

reduxForm({
  form: 'myForm',
  destroyOnUnmount: false
})(MyForm)

Migration Path

If starting a new project or refactoring:

  1. Evaluate if you truly need form state in Redux (cross-route access, time-travel debugging)
  2. If not, migrate to React Final Form (similar API, no Redux dependency)
  3. If yes, ensure Redux Form v8+ for React 16.8+ compatibility

Debugging Tips

Enable Redux DevTools to inspect form actions:

  • @@redux-form/CHANGE - Field value updates
  • @@redux-form/FOCUS / @@redux-form/BLUR - Field focus states
  • @@redux-form/ARRAY_PUSH - Dynamic array field operations (see src/actions.js for full list)

Check form state structure:

// In Redux DevTools or connected component
console.log(state.form.myForm)
// Structure: { values, initial, fields, error, warning, submitting, ... }