Electron-React Boilerplate: Redux-Form, Creating Form Field Components and Form Components With Redux and createSlice

Matthew Staniszewski
14 min readNov 13, 2020

I want to share a guide on how I set up Redux-Form for the Electron-React Boilerplate V1.3.1. The instructions will only be for Windows setup for now. Redux-Form is a nice way to setup form fields and pass form info and state to the store. createSlice was new to me and was well worth the time to learn it.

My hope is to help explain some of the dynamic setup of of single form field components can be used to create a form. I want to show how default values can be set on form fields and allowing it to change and updated to state on submit. And Most of all help explain how setup and use redux-form.

The benefit of this setup is when you need to create multiple form fields in different forms, you only need to import that specific form field component instead of creating it from scratch. The other benefit is if the specific form field type requires specific control on all the inputs, you only need to update the form field component in one location that gets applied to where ever it is used.

Please use my GitHub Repo Electron-React Boilerplate Tester template that will have the setup, styling, and form components that was created with this guide. The current Boilerplate Version 1.3.1 has the required Redux and Redux-Thunk for middleware already added but will be removed in the future.

The guide will show how to create the following form field type components:
Text Area Field
Input Field
Radio Buttons Fields
Drop-Down Fields
Check Box Fields

Install Redux-Form

Before we can get started, redux-form needed to be added to our dependencies. I ran the following command in a terminal to add redux-form:

yarn add redux-form

Because we are using TypeScript, I installed the redux-form TypeScript library into the dev dependencies by running the following command:

yarn add @types/redux-form --dev

Sidebar: Redux with Slice Setup on V1.3.1

The newer Electron-React Boilerplate V1.3.1 is a nice update to Redux using Slice. I originally used V1.1.0 for my work application and the difference appears to reduce the complexity of the folder structure and setup on V1.3.1. The app/store.ts file takes care of the dev, production, and build setup without having to have them in separate files and having to create TypeScript lines for each file. The other nice thing is the app/rootReducer.ts is the only reducer file required rather than having to setup types file along with a specific reducer file. Now we can generate a slice file to control state, action, and dispatch all in one. I believe this reduced some of the complexity in setup from the original V1.1.0.

I set up the form fields on the app/FormTypes.ts as the display page and can reference my Medium Instructions if you wish to see how it was originally set up.

Adding Redux-Form to Combine with Reducer

Before Redux-Form can submit information, it needs to be added to the app/rootReducer.ts.

app/rootReducer.ts File Setup
rootReducer.ts Setup for Redux-Form

Redux-form library was imported and renamed the variable name as fromReducer. The combineReducers object name “form” with the fromReducer as a string allows form information to be submitted. The information passed is in object with the key name that was set to the form you submit. You will be able to see all this in the action console logs once we get more setup.

Creating and Using Text Area Form Component

To start I added a folder to store the different form field component files in app/components/formTypeComponents since each is its own reusable component. Next, I added the Text Area Form Field component by adding the file TextArea.tsx to the formTypeComponents Folder. Use the following code to make the text area form field with redux-form.

Text Area Component File Location

I also created a CSS file, formStyling.css, that will control all the form component field styles. I am not going to go into detail on any of the stylings. I tried to organize the styling files that affects the display in the specific file component. Again reference my GitHub Repo if you wish to review how I set up the CSS styling.

The textarea Form Field Component code:

TextArea.tsx File Setup

You can see through the interface Props that we are passing Redux-Form props that we can then control the input. React feature useState is a greate way to setup component specific state. This is used to update the text box string as the user types into the specific form field component. Now this is a textarea specific component since <textarea> element is being used to setup a text box field.

Property onChange allows the call of the valueChange function for each time there is a change in the text box. This controls the input and limits the text that is allowed to be typed. This also allows us to update only the string values we want to allow to the component state. This also controls the string that will be submitted.

The <p> is used to display error messages that can be passed through props. I set this display to be hidden until there is an error passed through props after it has been touched. Then the error message is displayed under the text box. Once the error clears, the <p> element is then hidden. This is done by using condition rendering {boolean && (<someElement>)}. I used both error and touched to set the boolean(truthy) on when to display the error element. This was just my own personal preference keep the <p> element from taking up space on the DOM until there is an error.

Create Form Component

To use the textarea field component, we will create a form component that can add the different field components. The form component file FormFieldsForm.tsx I created is located in app/features/formTypes/formFieldsForm and along with a styling file FormFieldsForm.css.

FormFieldsForm Component File Location

FormFieldsForm.tsx Form Component Code:

Form Component With Text Area Fields

In this file you can see where I added the TypeScript interface for redux-form, setup the <form> that holds individual form components by creating a <Field> element. FormTextArea is imported and set to the <Field> component property.

The component textarea-specific properties are aria-multiline and rows. Any time we create a <Field> element, we need to include a label and name property that is used when the form is submitted. The defaultValue property is used to pass default values to to individual field components and will show up through props, in my case I named the textarea props as propsTextArea.

Because I am setting up default values for all types of form fields, the initialValues object is a form component specific property. This allows initialized values to the specific form component to be passed through the initialValues object property. There are other ways to pass initial values but this was the easiest way to set and send the default values without having issues of re-initializing to the form state and causing the form to refresh every time there is a change.

The validation function is a form specific HOF (Higher Order Function) for validating user inputs on each form field added to the form. This is also where we send errors to specific form field components. All the error handling is just examples and can be changed or add more based on your own requirements.

I included a submit button that uses the action function as the callback function. The action function submitFormTypes is passed through the form component property, onSubmit but it needs created yet.

Setup A Redux Slice

The next setup is the redux slice file to handle the actions, reducer and state. I created the file formTypesSlice.tsx that will handle all the form information and update state. This will all us to display the form information later as we submit the form. I created the formTypesSlice.tsx file in app/features/formTypes as seen in the folder screen shot above.

formTypesSlice.tsx Code:

Slice File Setup

Quick Break Down of Slice File: I set the default state name formTypes with default strings for each textarea key. Then created the reducer function storeTextArea to store information from the summited form in the state. Sorry, the name could have been better named to storeFormValues or something to that sort. Next the action function for the form submit callback named formData. Last I created formTypesState as a method that returns the formTypes store state.

Adding Form Component to Display Page

This is all then wrapped into the Form Types display page. FormTypes.tsx file at app/features/formTypes was updated to this:

Form Component with textarea Form Fields

Break Down of FormTypes.tsx display page component:

React-redux is imported to get the slice state and allow the use of dispatch in calling the slice action functions. The FormFieldForm component is imported to display the form with all the fields added to it. An anonymous function needed to be used to pass through property onSubmit. This allows us to pass the use of dispatch that calls the action function formData.

The field values are displayed to show the current field values and the updated state values as the form is submitted. When you submit a form, you can also see in the action console logs how redux-form and store state is updated on each event.

For my setup, the default state should show the default string in the textarea when the page is first loaded. Now you should be able to change the text box values and see how the value limitation works. The form error handling is set and should see the red errors pop up under the form fields once the error setting is reached.

I setup the form this way to imitate how you can store get request information from a DB to state that then can be displayed when the form component is loaded with all the original form information.

At this point, the Form Types page should be able to display the text area inputs once the form has been submitted. Each time you change the inputs, the state is updated and displayed on the Form Value State On Submit:

Text Area Display When First Loaded
Text Area Test Input

Input Form Field Component

Now that we have our textarea form component setup and working, let's add the input form component. I’ll include some extra features that may be good to know.

I created a file InputField.tsx file in app/components/formFieldComponents.

InputField.tsx File Location

The InputField.tsx Component Code Setup:

InputField.tsx Update For Input Fields

Here you can see this is a input specific component since <input> element is the main field element. The toCap is a custom field property to show a method to pass your own information type. You can see in the valueChange function that it is used to capitalize all letters if true. This is an example on how you can change an input field behavior with a custom property. I also changed up the limitations on the user input. Input 1 and 3 uses letters and numbers only while input 2 uses numbers only.

Important: We need to setup useState with an initial state to an empty string if a default value isn’t passed. This resolves a state control error when no default values are sent in redux-form fields components. When redux-form starts with blank fields it tries to control state but it is being controlled by the field component.

Add Input Field Component to Form Component

Here is where I added the input field component to the form component file FormFieldsForm.tsx in app/features/formTypes/formFieldsForm:

FormFieldsForm.tsx File Location

This is the code I added to the FormFieldsForm.tsx file:

Added Input Field Component Code To Form Component

You can see where I added the custom toCap property to be passed on input field component input1 only. This way only input1 has all letters capitalized but you can the property name option to other input form field components if desired. Some different error checking examples were changed where input2 form field only takes numbers and input1 and input3 takes numbers and letters.

We can enforce input2 to only allow number inputs by adding another custom boolean property to allow numbers only but since we control it on the single form I didn’t feel the need to at this point. I have default value examples being passed in input 1 and input 3 to display when the form loads.

Add Input Form State to Slice

Before input form field information can be displayed, the slice file needs state updated with the new input forms. Here is the added code for the slice file formTypesSlice.ts in app/features/formTypes/formFieldsForm:

formTypesSlice.ts location

formTypesSlice.ts Updated Code:

Slice Input Form Field State

Since the Slice file is already setup, only the initial state and reducer action require an update. I added default string values to input 1 and input 3 here.

Displaying Input Field Data

To display the input form fields and submit information, I updated the following code to the file FormTypes.tsx in app/features/formTypes/formFieldsForm:

FormTypes.tsx File Location

FormTypes.tsx Updated Code:

Input Field Display State Data

Now when we first load out Form Types page you should see this:

Default Display of Form Types Page

Here is what the input errors should look like when the validation errors on the form component are triggered and display the field component error tag:

Errors Form Types Display Page

Here is a example of a successful form submit and the right side displaying updating from the state update:

Successful Form Submit Display Page

Create the Radio Button, Drop-Down, and Check Box Components

I have shown how to setup the textarea and input form field components, validation error handling, limiting user input. Here I will create the radio button, drop-down menu, and check box components.

NOTE: I am speeding up a bit here since most of this has a similar setup and to help keep down how big this is getting already.

I created the files DropDown.tsx, RadioButton.tsx, and CheckBox.tsx in the app/components/formFieldComponents folder:

Radio Button, Drop-Down, And Check Box Component File Location

Drop-Down Component Code:

Drop-Down Menu Component Code

For the Drop-Down component, the renderOptions function is used to map out an array of drop down options that is passed through the component props. The { option } in renderOptions creates an empty space in the beginning of the list. I set the options key name and value pairs to be the same value. A default value can be passed to select and display a specific menu item once the drop-down component field is loaded. In this case, I have used the value property to pass the default drop-down item.

Radio Button Component Code:

Radio Button Component Code

Since Radio buttons are usually grouped together, I didn’t add the error and touch properties to display an error. You will see that this done when we create a separate form field component with several radio button options grouped together. This allows the error to show under the group of radio buttons rather than under each individual button. I will do the same for the Check Box component but know you don’t have to do it this way.

Check Box Component Code:

Check Box Component Code

For the Radio Button and Check Box components, I included a way to set default values for the individual field component. To use the radio button as a group of options I had to setup a separate form field component with a set of the radio button fields. This ties the set of radio buttons together so it sends back only one of the selected options on submit.

My thought process here was to help keep the organization of field components to the form component rather than adding all of them individually to the form component. For me it helped keep things separate for styling and organization.

I created two Radio Button field component groups. The first one allows default options to be passed while the second will be blank until the user selects one. I did the same thing for the Check Box components. The files I created where CheckBoxOptions1.tsx, CheckBoxOptions2.tsx, RadioButtonOption1.tsx, and RadioButtonOption2.tsx with a single styling file that was able to be applied to all four components. The file CheckRadioStyling.css in the folder location app/features/formTypes/formFieldsForm:

Radio Button and Check Box Component Field List File Location

Radio Button Field Group Component With Default Values:

Radio Button List Field Component with Default Value Setup

Radio Button Field Group Component With No Default Values:

Radio Button List Field Component with NO Default Value Setup

Check Box Field Group Component With Default Values:

Check Box List Field Component with Default Value Setup

Check Box Field Group Component With No Default Values:

Check Box List Field Component with NO Default Value Setup

Now we can add the Radio and Check Box grouped field components and the drop down components to the form component. Here I updated FormFieldsForm.tsx in same folder location app/features/formTypes/formFieldsForm/. I added two different Drop-Down components, again first one with default value setup and the second one without:

Form Component with Check Box, Drop-Down and Radio Button field component lists

The Check Box fields checkBoxOptions1 and 2 doesn’t need need a state value. Since we allow all check boxes to be selected we require each check box to have there own name and wont be using the props name inside the checkBoxOption components. We still need the name property since redux-form requires it on all <Field> components.

formTypesSlice.ts Form Field Value and State Updated Code:

Slice State with Radio Button, Drop-Down and Check Box Values

Since I am allowing all check box values to be selectable instead of one, I have to have a state value for each check box to track.

The final Setup is the Form Types display page to show the submitted form info from state. I updated the FormTypes.tsx in app/features/formTypes with the new state values and updated the default state values to pass to the form component.

Form Type Display of Radio Button, Drop-Down and Check Box Submitted Values

Now that the Form Fields were created and added to the form component, the form slice was updated with the form field state values and state update values and the display page displays the state change when the form is submitted, this is what the initial page should look like.

Initial Form Types Display Page

All the default values auto populate the form fields and are also displayed as the original state to the right. All fields should be able to be changed and update state once the form is submitted:

Form Type Display Page Update Form Submit

Conclusion

I hope this helps explain how setting up reusable form field components allows for better control. There should be a better understanding on how to setup a form with the different field components. Displaying a form component is added to a display page component.

State, reducer and dispatch is all controlled through the slice file. Input limitations can be controlled through the form validation or by limiting the input directly in the field component.

I enjoyed setting up the redux-form instructions because it helped reinforce what I learned and improve some of the original setup I had done in the past.

If you read this, I would love some feed back if something needs clarified or improved. Happy Coding!

--

--

Matthew Staniszewski

I am an electrical engineer that enjoyed a programming boot camp for web development. I learned the Electron-React Boiler plate to design and create a work app.