Control Component
Prop Types
model
(required)mapProps
updateOn
defaultValue
debounce
validators
validateOn
asyncValidators
asyncValidateOn
errors
parser
changeAction
controlProps
component
ignore
disabled
getRef
persist
getValue
isToggle
<Control>
The <Control>
component represents a form control, such as an <input />
, <select>
, <textarea />
, etc.
It is a connected component, and will use the model
prop to connect itself to the Redux store and dispatch the appropriate actions for each event handler.
The following pre-defined <Control>
s are available:
<Control>
or<Control.input>
for standard<input />
controls<Control.custom>
for controls without any default prop mapping<Control.text>
for<input type="text" />
<Control.textarea>
for<textarea></textarea>
<Control.radio>
for<input type="radio" />
<Control.checkbox>
for<input type="checkbox" />
<Control.file>
for<input type="file" />
<Control.select>
for<select></select>
<Control.button>
for<button></button>
<Control.reset>
for<button type="reset"></button>
You can add other input types to the basic <Control>
component as an attribute:
<Control type="password">
For making custom controls that work with React Redux Form, see the custom controls documentation.
Note: Any standard valid control props, such as name, disabled, onChange, onBlur, onFocus, onKeyPress
, etc. will be passed directly to the control, so feel free to use them.
import React from 'react';
import { Control } from 'react-redux-form';
class App extends React.Component {
render() {
return (
<form>
<label htmlFor="user.name">Name:</label>
<Control.text model="user.name" id="user.name" />
<label htmlFor="user.faveColor">Favorite color:</label>
<Control.select model="user.faveColor" id="user.faveColor">
<option value="red">red</option>
<option value="green">green</option>
<option value="blue">blue</option>
</Control.select>
</form>
);
}
}
export default App; // no need to connect
Prop Types
model="..."
(required)
(String | Function): The string representing the model value in the store.
// in store.js
export default createStore(combineForms({
'user': { name: '' },
}));
// in component's render() method
<Control.text model="user.name" />
It can also be a function that returns a string model. See the documentation on tracking for more information.
mapProps={{...}}
(Object | Function): A custom mapping from props provided by Control
to props received by the component. Can be:
- An object, where each value is a function from original props to corresponding value in result props.
- A function from original props to result props.
Examples:
<Control
mapProps={{
customChange: (props) => props.change,
}}
model="..."
/>
<Control
mapProps={({change}) => { return {customChange: change}; }}
model="..."
/>
See the documentation on custom controls for more information.
updateOn="..."
(String | Array): A string/array of strings specifying when the component should dispatch a change(...)
action, with one of these values:
"change"
- will dispatch inonChange
"blur"
- will dispatch inonBlur
"focus"
- will dispatch inonFocus
So, <Control model="foo.bar" updateOn="blur">
will only dispatch the change(...)
action on blur.
You can also specify updateOn={['change', 'blur']}
as an array of one or more of the above values.
Notes
- Use the
changeAction
prop if you want to dispatch custom actions along with theactions.change(...)
action.
defaultValue="..."
(Any): Sets the default value for the control. boolean
for checkboxes, string
for text input/textarea etc.
Notes
validators={{...}}
(Object): A map where the keys are validation keys, and the values are the corresponding functions that determine the validity of each key, given the model's value.
For example, this control validates that a username exists and is longer than 4 characters:
<Control.text
model="user.username"
validators={{
required: (val) => val.length,
length: (val) => val.length > 4
}}
/>
Notes
- If using ES2015 and you have validator functions, you can do this destructuring shortcut:
const required = (val) => val && val.length;
const length = (val) => val.length > 8;
<Control.text
model="user.username"
validators={{ required, length }}
/>
debounce={...}
(Number): The time in milliseconds, by which the change action will be debounced.
validateOn="..."
(String | Array): A string/array of strings specifying when validation should occur. By default, validation happens with whatever updateOn
is set to. The validateOn
property can have these values:
"change"
- validate on theonChange
event handler"blur"
- validate on theonBlur
event handler"focus"
- validate on theonFocus
event handler
Notes
- Validation will always occur on load; i.e., when the component is mounted. This is to ensure an accurate validation state for a new form.
- To avoid displaying error messages on load (as controls might be invalid), use the
.pristine
property of the control when conditionally showing error messages, or use the<Errors>
component.
asyncValidators={{...}}
(Object): A map where the keys are validation keys, and the values are the corresponding functions that (asynchronously) determine the validity of each key, given the model's value.
Each async validator function is called with 2 arguments:
value
- the model valuedone(validity)
- a callback function that should be called with the calculated validity
For example, this control validates that a username is available via a promise:
// function that returns a promise
import isAvailable from '../path/to/is-available';
<Control.text model="user.username"
asyncValidators={{
isAvailable: (value, done) => {
isAvailable(value)
.then((result) => done(result));
}
}} />
Notes
- Async validators will run on
blur
, unless you specify otherwise in theasyncValidateOn="..."
prop.
asyncValidateOn="..."
(String | Array): A string/array of strings specifying when async validation should occur. By default, validation happens on "blur"
. The asyncValidateOn
property can have these values:
"change"
- validate on theonChange
event handler"blur"
(default) - validate on theonBlur
event handler"focus"
- validate on theonFocus
event handler
errors={{...}}
(Object): A map where the keys are error keys, and the values are the corresponding error validator functions that determine the invalidity of each key, given the model's value.
An error validator is a function that returns true
or a truthy value (such as a string) if invalid, and false
if valid.
For example, this control validates that a username exists and is longer than 4 characters:
<Control.text
model="user.username"
errors={{
isEmpty: (val) => !val.length,
tooLong: (val) => val.length > 16,
}}
/>
parser={() => ...}
(Function): A function that parses the view value of the control before it is changed. It takes in one argument:
value
- the view value that represents the next model value
Example
function toAge(value) {
return parseInt(value) || 0;
}
<Control.text
type="number"
model="user.age"
parser={ toAge }
>
changeAction={() => ...}
An action creator (function) that specifies which action the <Control>
component should use when dispatching a change to the model. For example, this action is similar to:
actions.change(model, value)
for text input controlsactions.toggle(model, value)
for checkboxes (single-value models)actions.xor(model, value)
for checkboxes (multi-value models)
The action creator takes in two arguments:
model
- the model that is being changedvalue
- the value that the model is being changed to
Example
To create a custom <Control>
that submits the form on blur:
import { Control, actions } from 'react-redux-form';
const submitPromise = ... // a promise
function changeAndSubmit(model, value) {
return (dispatch) => {
dispatch(actions.change(model, value));
dispatch(actions.submit('user', submitPromise));
};
}
// Then, in your <Control> components...
<Control.text
type="email"
model="user.name"
changeAction= { changeAndSubmit }
updateOn="blur"
/>
Notes
- Use
changeAction
to do any other custom actions whenever your value is to change. - Since
changeAction
expects an action creator andredux-thunk
is used, you can asynchronously dispatch actions (like the example above).
controlProps={{...}}
(Object): A mapping of control-specific props that will be applied directly to the rendered control. In some cases, this can be a safer way of applying props, especially if there are naming conflicts between <Control>
-specific props (such as "model"
) and props that need to go on the rendered control (e.g., <input {...props} />
).
The normal behavior is that any extraneous props on <Control>
that are not part of Control.propTypes
(which are documented here) will be given to the rendered input.
Example:
// Suppose your <CustomInput> takes in an "errors" prop:
<Control.text
model="..."
component={CustomInput}
controlProps={{errors: 'errors for CustomInput'}}
/>
component={...}
(Function | String | Node): A custom component can be passed into the component={...}
prop, and standard control props and event handlers (such as onChange
, onBlur
, onFocus
, value
, etc.) will be mapped as expected:
import { Control } from 'react-redux-form';
const MyTextInput = (props) => <input className="my-input" {...props} />;
// usage inside render():
<Control
model="user.firstName"
component={MyTextInput}
/>
ignore={[...]}
(String | Array): The event(s) that you want the <Control>
to ignore. This can be good for performance and/or for de-cluttering the console log.
For instance, if you don't care whether a <Control>
is focused or blurred:
// will ignore onFocus and onBlur
<Control
model="..."
ignore={['focus', 'blur']}
/>
disabled={...}
(Any): The disabled
prop works just like you'd expect for controls that support the HTML5 disabled
attribute.
However, in <Control>
, it can be a boolean, or a function, string, or object as a Lodash iteratee.
// Disable the submit button when the form is invalid
<Control.button
model="user"
disabled={{ valid: false }}
>
Submit!
</Control.button>
For example:
disabled={true}
ordisabled={false}
will disable or enable the control respectively, as will any other primitive value, such asundefined
,null
, or a numberdisabled="touched"
will disable if the field istouched
(works with any property on the field)disabled={{ valid: false, touched: true }}
will disable if the field is bothtouched
and notvalid
disabled={(fieldValue) => !fieldValue.valid}
will call the function provided with thefieldValue
to determine itsdisabled
state.
(since: version 1.3.0)
getRef={() => ...}
(Function): Calls the callback provided to the getRef
prop with the node instance. Similar to ref
.
<Control.text
model="user.name"
getRef={(node) => this.attach(node)}
/>
persist={false}
(Boolean): Signifies that the field state (validation, etc.) should not persist when the component is unmounted. Default: false
// If user.name is less than 8 characters and persist == true, its validity will be:
// { length: false }
// even when the control is unmounted.
<Control.text
model="user.name"
validators={{ length: (value) => value.length > 8 }}
persist
/>
getValue={(event, props) => ...}
(Function): Determines the value given the event
(from onChange
) and optionally the control component's props
.
By default, the getValue
function returns the value by checking if the event
is a DOM event.
- If so, it returns
event.target.value
- If not, it returns the
event
.
For <Control.checkbox />
, the default getValue
function is:
- the original
value={...}
passed into the control, for multi-checkboxes (e.g.,model="user.hobbies[]"
) - the inverse boolean value of the
modelValue
.
<Control.text
model="user.name"
getValue={(event) => event.target.value}
/>
isToggle={false}
(Boolean): Signifies that the control is a toggle (e.g., a checkbox or a radio). If true
, then some optimizations are made.
Default: true
for <Control.radio>
and <Control.checkbox>
, false
for all other controls.
withFieldValue={false}
(Boolean): When true
the fieldValue
prop is mapped on to the child component. This prop contains information about the field's state such as its validity and whether it has been touched. This is particularly useful when using a custom component as it allows you to dynamically alter the component based on the field's state.
Default: false