How to Create a Redux-Form with Validation and Initialized Values

How to Create a Redux-Form with Validation and Initialized Values

You want your React app to have an intelligent form that validates the data being input before sending it off to your API. You want it to be easy and straightforward to implement with the features you’d expect. Features like setting initial values of your fields. Luckily for you, Redux Form makes all that a breeze. Even better, with the latest release candidate (Redux Form 6.0.0rc3) and later, you can upgrade to the latest version of React and not have those pesky unknown props errors bring your project to a screeching halt.

This tutorial is going to help you set up a Redux Form that uses the latest syntax, and how to get that form set up with some simple validation and initial values. We’ll be pretending that we’re creating an “update user information” form for a hypothetical application. The form is going to have access to actions to make submissions, and we’ll work under the assumption that we’ve stored our user information in the user reducer.

Install the Redux Form 6.0.0 release candidate (or later)

We’re going to be using the latest Redux version (at the time of this writing), 6.0.0-rc.3 for this tutorial. This is because with the changes made in React 15.2 (and later) standard releases of Redux-From don’t work without throwing a plethora of bugs. Furthermore, the syntax of Redux Form has been modified to streamline and simplify the process of creating and managing your forms. There’s no point in learning a syntax that’s going to be absolute as soon as the release candidate is published, so let’s get a head start!

Open up your console and use NPM to install the Redux Form release candidate:

npm install --save redux-form@6.0.0-rc.3

Our tutorial will also be dependent on react and react-redux, so make sure you have the latest versions of those installed as well.

Setting up your component

Opening up a blank document we want to import the dependencies we’re going to need to create our form. The form we’re making is connected to our application state, and will have an awareness of the actions we’ve created elsewhere in the project. This allows our form to send values to an API or another service directly.

You’ll notice that we brought in our application state (user) and set it as props at the bottom. This is going to allow us to initialize our form with data that’s already defined in our state.

Defining your form

The first thing we want to do is define our form. So just underneath our dependencies, outside of the scope of the component, add the following:

const form = reduxForm({
form: 'ReduxFormTutorial'
});

Handling the validation of our form can get messy if we do it “inline” as part of the render function of our component. So to clean that up and make it reusable (plus easier to manage), create a const that returns the input and logic for any errors that our field receives:

Now we need to define the redux form required property handleSubmit inside the render function of the component. Without this, the form simply will not work at all, and you’ll get a bunch of ugly errors.

const { handleSubmit } = this.props;

It’s time to start making up our form! Inside the render() function return the following example form. Make sure to use the <Field/> component imported from redux form in place of <input />.

At this point, your form should function properly, that is if this.props.submitFormActionwere to point to an existing action that we had created. However, our form doesn’t have any sort of validation or initial data prefilled into the fields. And those are nice, we want those.

Initialize your form with data

For our example here we’re pretending that our form handles updates to our user’s information. We wouldn’t want them to have to type in all of their information every time they switch email accounts or phone numbers. So we want the form to initialize with their existing information which can then be altered in whatever way they wish.

Now, we can create our function and define the initial values. Afterward, we call the redux form property initialize and pass it our data. The objects names must correlate with name property of our <Field />‘s above.

It’s as easy as that. When the component mounts, it will define our values and push it to the form’s fields.

Adding form validation

The last thing we want to do now is add in some sort of form validation to make sure all the fields have something in them and it’s of the appropriate format. Outside of our component, we want to define a function called validate that will take our formPropsand run them through various tests.

We’re going to make a quick jog back up to where we defined our form and add one more line to check our properties against our validation criteria. This process will also check our fields against HTML validation that was defined when we set the <Field />property type to “email” (for example).

const form = reduxForm({
form: 'ReduxFormTutorial',
validate
});

And there you have it! Your redux form is now set to initialize with values, validate itself before submitting, and then pass it’s approved values to your action. Redux form is truly one of the most pivotal dependencies you will integrate into your application so getting a strong understanding of it is important.

That’s all for now and thanks for reading! Once again, you can view the complete source code here. And if you have any questions, comments, or want to suggest a topic for me write about next, just leave it in the section below!

Thanks for this tutorial, it was really helpful. I must admit I have battled a bit with version 6 of redux-form. I have found that the renderField works great for simple, traditional input fields, but does not seem to work so well for selects or multiple checkbox groups. In your example you have validation on everything except the select, I am interested to know how you might achieve adding this.

If you were developing a large application with multiple forms, how might you abstract the renderField and the validation to become reusable. This is something I could do with version 5, but am struggling to get it working for version 6.

Validation works just as well with the field, it was a lapse in my part not to include it. I will go back and update that. As for making the validation reusible I was able to make a single ‘form_validate’ file and just import it into all of my forms. However, field naming conventions would need to be more strict in my opinion to make this work. I really do like how it cleans up my components though, so I’ll probably start doing this from now on. Even if it means just exporting different form validations from that one file, it just looks cleaner and keeps it much more simple.

The one thing I haven’t done yet is verify that you could do something similar with the “renderField” components. I feel like handling passing the field props, the form state and values, etc would be more difficult then efficient in that case.

Hey quirksmode, I wanted to follow up with you. I moved all my fields into another file and exported them. It works perfectly when you import them into your forms, like you suggested. It’s amazing, cleans everything up beautifully and prevents a lot of redundancies when making multiple forms across your application. Thought you’d like to know!

quirksmode

Hey David, this sounds great, do you have a working example I could take a look at?

Great read, there doesn’t seem to be anything tying this to the redux implementation from what I can see. I can not see why I can not use this with other flux implementations or just react on its own. Is this correct? If so, is the name, redux-form a little restrictive maybe?

Emanuele Ingrosso

Well you also need to setup a form reducer on the redux store, because the form data and status will live there.

Thank you. What if, phonenumber field has to allow user to enter only numbers and validate as the user types in and show error message instantly.I tried with field.dirty but that shows “phone number is required” always which should happen only on blur.Is there any way of achieving this redux-form?

Thank you for the reply.But the problem with that will be i can see the error message only after phone number looses focus.Requirement is to show the message as user types.I got it using event’s onchange method but i would like to know if it can be done by redux-form.

I just keep getting error handleSubmit is not a function . Can you please tell me how to get rid of this?

Lucas Gonzalo Michailian

This line: this.props.initialize(initData); Save my day !

Sunil Kumar Banjare

Great example Have one doubt.
How can we autofill the data when we already have some data like contact number, address, want whenever click on edit button, call on method and it should be autofill with given data?

Subscribe to my mailing list

View older content

Keeping the lights on

To put it simply, I want to make a little extra to justify the amount of time and effort I put into this website. I love writing these tutorials, so every bit helps make it possible. Don’t worry, my advertising will never become intrusive. I value your readership and thank you for your support!