The best way to manage the state of your form using React and Redux. The basic idea is to manage each input state in redux instead of managing it in components one by one and reduce a bunch of lines of code with react redux forms.
Redux form works with react and redux to make an HTML form simple by storing all of its states in a familiar place to share later.
Table of Contents
Prerequisite
Before getting starting the react redux forms one has very basic knowledge of the following
- React and Higher Order Components (HOC)
- Redux state management
After having some basic knowledge of React and redux it will be effortless and simple to understand and implement the react redux forms. If you have the above knowledge you are good to go with react redux form.
There are many libraries that can help you to build react redux forms but the most popular and simplest library is redux-form
Getting Started with React Redux forms:
Overview:
To connect your react form component with your redux component or store you need to use the following form redux-form:
- Redux Reducer: formReducer
- React HOC reduxForm() and <Field /> Component
It’s really important to understand the above redux form reducer and components in this redux form tutorial.
Redux Reducer (formReducer):
Redux Reducer (formReducer) function basically tells how to update a redux store whenever there is a change coming from the redux form application described by the Redux actions
React HOC (reduxForm()):
React component (HOC reduxForm())) can take configuration options and returns a new redux form function. You can wrap your react redux form component and dispatch changes that occurred by the user interaction using redux actions.
React Component (<Field />):
React component (<Field />) placed in the react redux form component. You can use it to build your form and perform its functions using redux-form.
Installation:
Let’s start by creating react app using create-react-app package. create-react-app will allow you to create react app with no configuration. You can use it in the terminal/command line using the create-react-app command. It automatically creates a React app in a folder named react-redux-form.
npm install -g create-react-app // npm version < 5.2 create-react-app react-redux-form // npm version >= 5.2 npx create-react-app react-redux-form
And start server
npm start
We now have react app up and running.
Now install the dependencies to create the react redux forms.
npm install --save redux redux-form
Step 1: Create Redux Store:
Create a simple redux store for the redux form which will save the form state and update the subscribers wherever you will use it.
// src/store.js import { createStore, combineReducers } from 'redux'; import { reducer as formReducer } from 'redux-form'; // combine all reducers to create a redux store const reducers = combineReducers({form: formReducer}); // create redux store using above combined reducers const store = createStore(reducers); // export redux store to use it in the application export default store;
Now your store knows how to handle changes coming from the redux form component through actions.
Step 2: Create and Register Redux Form:
Now create a form that can be used for the redux form.
// src/profile.js import React from 'react'; import { Field, reduxForm } from 'redux-form'; const ProfileUpdateForm = props => { const { handleSubmit, pristine, reset, submitting } = props; return ( <form onSubmit={handleSubmit}> <div> <label>Name</label> <div> <Field name="name" component="input" type="text" placeholder="Name" /> </div> </div> <div> <label>Email</label> <div> <Field name="email" component="input" type="email" placeholder="Email" /> </div> // src/profile.js </div> <div> <label>Gender</label> <div> <label> <Field name="gender" component="input" type="radio" value="male" /> {' '} Male </label> <label> <Field name="gender" component="input" type="radio" value="female" /> {' '} Female </label> <label> <Field name="gender" component="input" type="radio" value="other" /> {' '} Other </label> </div> </div> <div> <button type="submit" disabled={pristine || submitting}>Submit</button> </div> </form> ); }; export default reduxForm({ form: 'profileUpdate', // a unique identifier for this form })(ProfileUpdateForm);
In the above code snippet of the redux form, you can see the <Field /> component that basically tells how you connect each input or field to the Redux store that is created in Step1. You need to know three fundamental things about the <Field /> component to use it correctly.
- The name prop is required and a string path. It is a string type, in dot notation (obj.name) or bracket notation (obj[‘name’]), or simple (‘name’)
- The component prop is required. It defines which component will be rendered (input, textarea, select, etc)
- All other props (onChange, onBlur, etc) will be added to the generated component as props.
In the above snippet, you have three fields that can be updated in the user profile update react redux form. Name and Email fields will render input HTML elements with text and email type respectively using the <Field /> component of redux form.
Another one is the reduxForm() Higher order component that binds the form to redux form and user interaction to dispatch redux actions.
So, in detail, you have created a file prfile.js in the src folder that has the form generated via the <Field /> component and registered as a redux form using reduxForm() higher-order component to dispatch the user interaction redux actions.
For example
- The user clicks on the submit button
- After that form onFocus dispatched and update the state in the formReducer
- The update state is then passed back to the form input(s)
Looking for React Development Team?
Share the details of your request and we will provide you with a full-cycle team under one roof.
Step 3: Render Redux Form
After creating react redux form the next step is to render that form so that the user can interact with it to manipulate the redux form state.
// src/App.js import React, { Component } from 'react'; import { Provider } from "react-redux"; import store from "./store"; import ProfileUpdateForm from "./profile"; class App extends Component { const handleProfileUpdate = (values) => { // print all form values in the console console.log(values); } render() { return ( <Provider store={store}> <div> <h3>Update User Profile</h3> <ProfileUpdateForm onSubmit={this.handleProfileUpdate} /> </div> </Provider> ); } } export default App;
In the above code react redux form code snippet you can see that you have registered the ProfileUpdateForm, and provided an onSubmit function that will be triggered when the user will click on the submit button.
In the handleProfileUpdate function, all form values will be logged in the console on react redux form submission. console.log(values) will print:
Step 4: Adding Validations
Whenever you build forms or redux forms validations are very important so that you have correct input from the user and convey the message to the user if there is any error in the given data.
To create validation of profile update redux form follow the below code snippet:
// src/validate.js export default const validate = val => { const errors = {}; if (!val.name) { errors.name = "name can't be blank"; } if (!val.email) { errors.email = "email can't be blank"; } else if (!/^.+@.+$/i.test(val.email)) { // simple email checking regex errors.email = 'invalid email address'; } return errors; };
Create a reusable components so that you don’t have to write validation for each input in the form.
// src/field.js export default const renderField = ({ input, label, type, meta: { touched, error, warning } }) => ( <div> <div> <label>{label}</label> <input {...input} placeholder={label} type={type}/> {touched && ((error && <span>{error}</span>) || (warning && <span>{warning}</span>))} </div> </div> )
Now in src/profile.js
// src/profile.js import React from 'react'; import { Field, reduxForm } from 'redux-form'; import validate from './validate'; import renderField from './field'; const ProfileUpdateForm = props => { const { handleSubmit, pristine, reset, submitting } = props; return ( <form onSubmit={handleSubmit}> <div> <Field name="name" component={renderField} /> </div> <div> <Field name="email" component={renderField} /> </div> <div> <label>Gender</label> <div> <label> <Field name="gender" component="input" type="radio" value="male" /> {' '} Male </label> <label> <Field name="gender" component="input" type="radio" value="female" /> {' '} Female </label> <label> <Field name="gender" component="input" type="radio" value="other" /> {' '} Other </label> </div> </div> <div> <button type="submit" disabled={pristine || submitting}>Submit</button> </div> </form> ); }; export default reduxForm({ form: 'profileUpdate', // a unique identifier for this form validate })(ProfileUpdateForm);
Now in the above react redux form snippet you can see that you have created a reusable component in src/field.js and validate function that will basically handle the react redux forms validation on submit and display errors with each field that has the validation. You can see in reduxForm (HOC) there is validate attribute that will run our validate function and in the <Field /> you have changed the component={“input”} with our custom field component component={renderField} which will render the reusable component with the proper error or warning if the input has been touched on focused.
Conclusion:
In this react redux form tutorial, you have built react redux forms and connected them with the redux form. You have added the form validation that will throw errors or warnings if anything is wrong with the form detail without using any extra library.
You can read more about redux-form on the official site and go through the examples in detail.