redux-formalize v0.1.3
Redux Formalize
Seamless management of stateless forms in your React/Redux app.
Install
yarn add redux-formalizeSetup
:one: Add a form reducer to your root reducer
import {formsReducerCreator} from 'redux-formalize';
const rootReducer = combineReducers({
[...],
forms: formsReducerCreator()
}:two: Add form meta to your actions
Ensure your asynchronous action triad for submitting the form (pending, success, and failure actions) have the same formName as given to connectForm below.
const actionCreators = {
saveFormValues(payload) {
const formName = 'myFormName';
return dispatch => {
dispatch({type: 'SAVE_FORM', payload, formName});
return post('/api/save', payload).then(
response => dispatch({type: 'SAVE_FORM_SUCCESS', payload, response, formName}),
error => dispatch({type: 'SAVE_FORM_FAIL', payload, error, formName})
);
};
}
};:three: Connect and configure your stateless form:
import {connectForm} from 'redux-formalize';
// your stateless form enhanced with handlers and form state provided by redux-formalize
function Form({fields, updateField, submitForm, state: {isSubmitting, errors}}) {
return (
<form onSubmit={submitForm} onChange={updateField}>
<p>
<label>
A Field:
<input type="text" name="text" value={fields.field}/>
</label>
</p>
<p>
<label>
Another Field:
<input type="radio" name="anotherField" value="foo" checked={fields.anotherField === 'foo'}/>
<input type="radio" name="anotherField" value="bar" checked={fields.anotherField === 'bar'}/>
</label>
</p>
<p>
<label>
Last Field:
<input type="checkbox" name="lastField" value="baz" checked={fields.lastField}/>
</label>
</p>
<p>
<button type="submit" disabled={isSubmitting}>{isSubmitting ? 'Submitting' : 'Submit'}</button>
</p>
</form>
);
}
const fieldNames = ['field', 'anotherField', 'lastField'];
// props are passed to your submit handler including any dispatched wrapped action creators
function onSubmit({saveFormValues, fields}) {
saveFormValues(fields.field, fields.anotherField, fields.lastField);
}
// connect the form
export default connectForm('myFormName', fieldNames, onSubmit, {actionCreators})(Form);That's it! :tada:
Redux Formalize will wrap your stateless form in a higher-order component that passes field values and form management functions as props to your form. Furthermore, actions dispatched with a connected form's name will have it's state automatically reduced and passed to your form as a state prop.
API
formsReducerCreator([config])
config- an optional object to configure the action type pattern matching of the reducer. Valid settings aresuccessMatch- a regex to match a successful form action type. Defaults to/_SUCCESS$/failMatch- a regex to match a failed form action type. Defaults to/_FAIL$/
Returns a reducer that will reduce new form state when an action is encountered containing the formName property. If the action type does not match the success or fail regex's defined above, it's assumed to be an action describing a form's "pending" state. Form state is reduced as follows for a given action type:
- Pending:
{isSubmitting: true, errors: undefined} - Success:
{isSubmitting: false, errors: undefined} - Fail:
{isSubmitting: false, errors}whereerrorsis taken from the failed action
The form state is reduced to a property keyed by the formName provided in the action.
connectForm(formName, fieldNames, onSubmit, [config])
formName- the name of the form. Any action associated with the form's submission must provide the same name as a property on the action for automatic form state reductionfieldNames- an array containing all field names of controlled elements within the formonSubmit- a callback function to be called when the form is submitted. The callback will be passed props containing field values and any action creators or handlers passed in the config defined below along with any custom props passed in on creation of the formconfig- an optional object to further configure the form. Valid settings areactionCreators- any action creators required to submit the form. This can be in any format accepted by themapDispatchToPropsargument of react-redux'sconnectfunctioninitialState- an object or function used to override the initial state of the fields in the form. If a function is given, it will be passed the current props and is expected to return an object containing the initial stateshouldResetFormOnProps- a function that is called with the current props and is expected to return a boolean designating whether or not the form should be reset based on the new props. By default, a function will be provided that simply returnsfalseif the form is submitting or contains errorshandlers- a convenience setting to allow for further handlers required to manage the state of the form to be passed in. For example, some custom form element components don't bubble anonChangeevent that the parentformcan handle so instead a handler can be provided that usesupdateFormto manually save the new field to state. The format of the handlers must conform to thehandlerCreatorsdefined in recomposeswithHandlersfunction
Returns a higher-order component that will supply the wrapped stateless form with the following props:
fields- an object containing the values of all controlled form fields with the field names as the keysstate- an object containing the state of the form. It will be comprised of anisSubmittingboolean indicating whether the form is submitting or not and, on failed form submissions, anerrorsobject taken from the failed form actionsubmitForm- a function to be used to handle the form'ssubmitevent. The function will simply prevent the event's default behaviour from executing before calling the suppliedonSubmitfunction passed toconnectFormupdateField- a function to be used to handle the form elements'changeevent. It can either be placed on each form element or on the parent form to handle anychangeevents via bubblingupdateForm- a convenience function which can be used to manually update form elements that either don't firechangeevents or may require specific processing to extract the required value before saving to state. Use this in combination withhandlersdefined above for custom form element change handling
Example
yarn && yarn start :thumbsup:
Use Redux DevTools to monitor the actions and state changes on form submission.