Redux is widely employed in React apps for robust state management. Key tools like Redux Form, Formik, React Final Form, and Redux Toolkit streamline form handling by centralizing input state management, validation, and submission processing. Integrating form state with the global Redux store ensures consistent behavior and enhances predictability in React applications. There are several libraries with their unique features which are used to facilitate this process.
Below are some common libraries/tools for form handling in Redux:
Redux Form used to be highly favored when it came to handling forms in strictly Redux based applications. It makes use of a Redux form higher-order component which actually connects those form components with a Redux store. Every field which belongs within any form becomes part of Redux state making this approach simple to enforce both validating inputs provided by users as well as dealing properly with submission errors or any possible field level error handling.
Strengths: - Integration: Deeply integrates with Redux making form state available throughout the application.
- Helpers: For field validation, normalization and parsing it offers a variety of helpers.
Drawbacks: - Performance: Due to frequent Redux state updates can lead to performance issues in large applications.
- Complexity: The API can be complex and challenging for the new users.
Installation:npm i redux-form dependency:
"dependencies": { "redux-form": "^8.3.9" } Example: This demonstrates ‘reduxForm’ HOC connects the form to the Redux store and ‘Field’ components are used to manage individual form fields.
import { reduxForm, Field } from 'redux-form';
const MyForm = ({ handleSubmit }) => ( <form onSubmit={handleSubmit}> <Field name="username" component="input" type="text" /> <Field name="password" component="input" type="password" /> <button type="submit">Submit</button> </form> );
export default reduxForm({ form: 'myForm' })(MyForm); Formik is a form library that manages form state locally within components. It simplifies the work of form validation, error handling and submission. By using Formik hooks like ‘useFormik’ and components like <Formik>, <Form> and <Field> forms can be managed without any dependency on Redux.
Strengths:- Ease of Use: Simple and intuitive API for form management.
- Flexibility: It can be integrated with Redux or can be used standalone.
Drawbacks: - Local State: Manages form state locally which might require extra steps to sync with Redux.
Installation:npm i formik dependency:
"dependencies": { "formik": "^4.0.0", } Example: This demonstrates ‘<Formik>’ component initializes form state and handles submission, ‘<Form>’ and ‘<Field>’ components are used to render the form and fields.
import { Formik, Form, Field } from 'formik'
const MyForm = () => ( <Formik initialValues={{ username: '', password: '' }} onSubmit={values => console.log(values)} > {() => ( <Form> <Field name='username' type='text' /> <Field name='password' type='password' /> <Field name='confirm password' type='password' /> <button type='submit'>Submit</button> </Form> )} </Formik> ) React Final Form is a lite and flexible approach for controlling the state of the form or state management. It focuses more on simplicity and performance. Form can also be connected to Redux in terms of custom reducers and actions through which the local form states can also integrate with the Redux store whenever necessary.
Strengths: - Performance: Efficiently manages form state updates.
- Simplicity: Provides a clean minimal API.
Drawbacks: - Manual Integration: To sync with Redux it requires custom code
Installation:npm i react-final-form dependency:
"dependencies": { "react-final-form": "^8.4.1", } Example: This demonstrates ‘<Form>’ component wraps the form, handling submission and ‘<Field>’ component is used for input fields.
import { Form, Field } from "react-final-form";
const myForm = () => ( <Form onSubmit={(values) => console.log(values)} render={({ handleSubmit }) => ( <form onSubmit={handleSubmit}> <Field name="username" component="input" type="text" placeholder="Username" /> <Field name="password" component="input" type="password" placeholder="Password" /> <button type="submit">Login</button> </form> )} /> ); The modern way of managing Redux state including form state should be known as Redux Toolkit. Through creating slices using reducers for form state, we can manage submission processes during updates with severally leveraging on Redux Toolkit features like ‘createSlice’ as well as ‘configureStore’.
Strengths: - Modern API: Aligns with contemporary Redux practices.
- Flexibility: Allows custom form handling logic tailored to specific needs.
Drawbacks: - Manual Setup: As compared to dedicated form libraries it requires more boilerplate.
Installation:npm i redux-form dependency:
"dependencies": { "@reduxjs/toolkit": "^1.9.2", } Example: This illustrates ‘createSlice’ creates a slice for form state with reducers to handle field updates and form submission, ‘useDispatch’ and ‘useSelector’ are used to connect the form component with Redux.
import { createSlice } from '@reduxjs/toolkit'; import { useDispatch, useSelector } from 'react-redux';
const formSlice = createSlice({ name: 'form', initialState: { username: '', password: '' }, reducers: { updateField: (state, action) => { state[action.payload.field] = action.payload.value; }, submitForm: (state) => { // Handle form submission }, }, });
export const { updateField, submitForm } = formSlice.actions;
const MyForm = () => { const dispatch = useDispatch(); const formState = useSelector((state) => state.form);
const handleChange = (e) => { dispatch(updateField({ field: e.target.name, value: e.target.value })); };
return ( <form onSubmit={() => dispatch(submitForm())}> <input name="username" value={formState.username} onChange={handleChange} /> <input name="password" value={formState.password} onChange={handleChange} /> <button type="submit">Sign in</button> </form> ); }; There are a number of steps that need to be taken in creating a Redux-based form application. They involve setting up the project, installing dependencies and integrating libraries for form handling. Using Redux Form as an example, here is a step-by-step guide:
Step 1: Create a New React Appnpx create-react-app redux-form-app cd redux-form-app Step 2: Install Required Modulesnpm install redux react-redux redux-form Step 3: Set Up Redux Store
JavaScript
// store.js
import { createStore, combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';
const rootReducer = combineReducers({
form: formReducer,
});
const store = createStore(rootReducer);
export default store;
Step 4: Integrate Redux with React
JavaScript
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Project Structure: Project Structure Updated dependencies in package.json file:
"dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^8.1.0", "redux": "^4.2.1", "redux-form": "^8.3.9" } Example: To illustrate the output, consider a simple login form created using Redux Form.
JavaScript
//store.js
import { createStore, combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';
const rootReducer = combineReducers({
form: formReducer,
});
const store = createStore(rootReducer);
export default store;
JavaScript
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './components/store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
JavaScript
//myForm.js
import React from "react";
import { reduxForm, Field } from "redux-form";
const myForm = ({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<div>
<label>Username</label>
<Field name="username" component="input" type="text" />
</div>
<div>
<label>Password</label>
<Field name="password" component="input" type="password" />
</div>
<button type="submit">Submit</button>
</form>
);
JavaScript
//app.js
import React from "react";
import MyForm from "./components/myForm";
const App = () => <MyForm />;
export default App;
Output:
 output of a form created using ReduxForm
|