Title: How to Set defaultValue to Input Component in Redux Form
Introduction
In Redux Form, setting a defaultValue to an input component may sometimes result in empty fields. This can be especially challenging when working with dynamic forms or using the FieldArray feature. In this article, we will explore different approaches to correctly set the defaultValue and ensure that the fields are populated as expected.
Method 1: Using initialize()
If you need to set default values that can be updated multiple times, you can use the initialize() method provided by Redux Form. By calling initialize() with an object of values, you can initialize the form fields with the desired default values. Here’s an example:
class MyForm extends Component {
componentWillMount () {
this.props.initialize({ name: 'your name' });
}
// If your data can be updated
componentWillReceiveProps (nextProps) {
if (/* nextProps changed in a way to reset default values */) {
this.props.destroy();
this.props.initialize({ ... });
}
}
render () {
return (
<form>
<Field name="name" component="..." />
</form>
);
}
}
export default reduxForm({})(MyForm);
This approach allows you to update the default values repeatedly. If you only need to set the default values once, you can use the following syntax:
export default reduxForm({ values: { ... } })(MyForm);
Method 2: Using initialValues
Another approach to set default values is by using the initialValues configuration in Redux Form. By providing the desired default values in the initialValues object, the form fields will be initialized with those values when the form loads. Here’s an example:
const renderMembers = ({ fields }) => (
<div>
<h2>Members</h2>
<button onClick={() => fields.push({})}>
add
</button>
<br />
{fields.map((field, idx) => (
<div className="member" key={idx}>
First Name
<Field name={`${field}.firstName`} component="input" type="text" />
<br />
Last Name
<Field name={`${field}.lastName`} component="input" type="text" />
<br />
<button onClick={() => fields.remove(idx)}>
remove
</button>
<br />
</div>
))}
</div>
);
const Form = () => (
<FieldArray name="members" component={renderMembers} />
);
const MyForm = reduxForm({
form: "foo",
initialValues: {
members: [{
firstName: "myFirstName"
}]
}
})(Form);
Method 3: Using a Higher Order Component (HoC)
Alternatively, you can create a Higher Order Component (HoC) to handle the initialization of defaultValue. This approach gives you more control over how the default values are set. Here’s an example implementation:
import { Component } from 'react'
import { change } from 'redux-form'
class ReduxFormInputContainer extends Component{
componentDidMount(){
const {
initialValue,
meta,
} = this.props
if(initialValue === undefined || meta.initial !== undefined || meta.dirty) return
const {
meta: { form, dispatch },
input: { name },
} = this.props
dispatch(change(form, name, initialValue))
}
render(){
const {
initialValue,
component: Compo,
...fieldProps
} = this.props
return <Compo {...fieldProps} />
}
}
function reduxFormInputContainer(component){
return function(props){
return <ReduxFormInputContainer {...props} component={component} />
}
}
export default reduxFormInputContainer
To use this HoC, you can wrap your input component with it. Here’s an example:
import reduxFormInputContainer from 'app/lib/reduxFormInputContainer'
InputNumericWidget = reduxFormInputContainer(InputNumericWidget)
class InputNumeric extends Component{
render(){
const props = this.props
return (
<Field component={InputNumericWidget} {...props} />
)
}
}
Conclusion
Setting defaultValue to an input component in Redux Form can be achieved using various techniques. Whether you choose to use initialize(), initialValues, or a Higher Order Component, it’s crucial to ensure that the default values are correctly assigned to avoid empty fields. Experiment with these methods and choose the one that best fits your specific use case.