# 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:
| Option | Type | Description |
|---|---|---|
form | String | Required. Unique form identifier |
validate | Function | Synchronous validation (values) => errors |
asyncValidate | Function | Async validation (values, dispatch) => Promise |
asyncBlurFields | Array | Fields triggering async validation on blur |
initialValues | Object | Default form values |
destroyOnUnmount | Boolean | Clear form data on unmount (default: true) |
forceUnregisterOnUnmount | Boolean | Unregister fields on unmount |
keepDirtyOnReinitialize | Boolean | Preserve 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
shouldComponentUpdateorReact.memoon custom field components - Debounce validation functions
- Consider
react-final-formfor 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:
- Evaluate if you truly need form state in Redux (cross-route access, time-travel debugging)
- If not, migrate to React Final Form (similar API, no Redux dependency)
- 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 (seesrc/actions.jsfor full list)
Check form state structure:
// In Redux DevTools or connected component
console.log(state.form.myForm)
// Structure: { values, initial, fields, error, warning, submitting, ... }