Using Redux Form to handle user input

  • The reduxForm() decorator function. This works similarly to react-redux’s connect() function — you wrap your component with it to enable redux-form functionality. Typically, the component you are wrapping is the one that contains the HTML <form> element. I’ll refer to this wrapped component as “the form component.”
  • Field and FieldArray components. You add Field and FieldArray as descendants of the form component. These, in turn, wrap the standard HTML input elements like <input> and <select>.

Using redux-form with custom components

1. reduxForm() wrapper component from redux-form.
2. My form component (with HTML <form> element).
3. Field component from redux-form
4. My component with react-bootstrap boilerplate.
5. FormControl component from react-bootstrap.
6. HTML <input> element.

The redux-form Field component

  • name. The same name prop you gave to the Field component.
  • input. An object containing all of the props that Field would have passed to a standard HTML input element: name, onChange and other event handlers and value. The value prop is what turns the input into a controlled component.
  • meta. An object containing status information about the field: has it been touched, is it pristine or dirty, validation error messages, etc.

The reduxForm() decorator

React's form onSubmit calls:
redux-form’s handleSubmit, which (if the form is valid) calls:
the function you pass in as a prop named onSubmit
class MyForm extends React.Component {
// this.props.handleSubmit is created by reduxForm()
// if the form is valid, it will call this.props.onSubmit,
// which I added below in the connect() function.
const { handleSubmit } = this.props
render() {
<form onSubmit={handleSubmit}>
<Field name='user.email' component='input' type='email' />
<Field name='user.name' component='input' />
...
<input type='submit' value='Save' />
</form>
}
}
// Your component is wrapped by redux-form
// with the configuration you specify
const myReduxForm = reduxForm({
form: ‘myFormName’, // required by reduxForm()
warn: (values, props) => { ... }, // optional
error: (values, props) => { ... } // optional
})(MyForm)
// Your redux-form-wrapped component is wrapped by react-redux.
export default connect(
state => ({
// optional. grab values to fill the form from somewhere.
initialValues: state.foo.bar
}),
dispatch => ({
// reduxForm() expects the component to have an onSubmit
// prop. You could also pass this from a parent component.
// I want to dispatch a redux action.
onSubmit: data => dispatch(myActionToDoStuff(data))
})
)(myReduxForm)

Where is the form data stored?

import { reducer as ‘formReducer’ } from ‘redux-form’
...
export default combineReducers({
// other reducers,
form: formReducer // must be named 'form'
})

Validation with redux-form

Values — nested or flat

{
email: 'askywalker@deathstar.com',
name: 'anakin'
side: 'dark',
aliases: ['darth vader', 'sith lord'],
}
{
user: {
email: 'askywalker@deathstar.com',
name: 'anakin',
side: 'dark',
aliases: ['darth vader', 'sith lord'],
children: {
luke: {
name: 'luke',
planet: 'tatooine'
},
leia: {
name: 'leia',
planet: 'alderan'
}
}
},
}
  • The initialValues prop you pass to reduxForm().
  • The names (or dotted paths) you give to Field components.
  • The values object passed to your onSubmit function.
  • The values object passed to your warn and error validation functions — and the objects you return from those functions.

More on validation

{
side: 'The dark side of the Force is not allowed.'
}
{
user: {
side: 'The dark side of the Force is not allowed.'
children: {
leia: {
planet: '"alderan" is not a planet. Please check the
spelling and try again'
}
}
}
}

Performance with large forms

Conclusion

--

--

--

Principal at Nevo.com. Software development, lean product development, continuous delivery, devops. New Yorker & Rhode Islander.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
John Bennett

John Bennett

Principal at Nevo.com. Software development, lean product development, continuous delivery, devops. New Yorker & Rhode Islander.

More from Medium

Inverse Data Flow — React.js

Application Framework with React.js and how to create frontend using React.js

Build a full-stack framework on React

Create dark mode structure in React projects (using Tailwind CSS, Typescript, and Custom Hook)