immutable-form
Getting Started
Install the package
yarn install immutable-form
To install the latest development version
yarn install immutable-form@devel
Documentation
Overview
The intent of this package is to provide a simple to use implementation of managing form state for React components, streamlining common requirements such as validation, error handling, data fetching and submission.
This package consists of three modules, Form
, FormCollection
, and connectForm
.
Form
is a class which provides an API to read and write form's state. The state is stored within a Immutable object which in turn is resides within a Redux store.
FormCollection
holds references to all existing forms. This is useful if you're trying to access form values across different components.
connectForm
is a React higher order component which passes down form
and field
props into your components and re-renders on the form's state changes.
Creating a form
import { Form, connectForm } from 'immutable-form';
const createUserPromise = Promise.resolve({
userId: '123',
});
const mapPropsToForm = ({
hasUsername,
hasPassword,
}) => new Form('userForm', {
fields: {
username: (hasUsername || undefined) && {
value: 'some value',
validate: [
username => username.trim().length === 0 && 'Username cannot be be empty',
],
},
password: (hasPassword || undefined) && {
validate: [
password => password.trim().length < 6 && 'Password must be longer than 6 characters',
],
},
},
})
.setSubmit((form) => createUserPromise)
.setOnSuccess(({userId}, form) => userId)
.setOnFailure((err, form) => err);
const UserForm = ({
// fields is a an Immutable Map
fields,
// This is the `Form` object, you can use it do extra actions such submitting the form.
form,
}) => (
<div>
<input
type="text"
onChange={(e) => form.setField('username', e.target.value)}
value={fields.getIn(['username', 'value'])}
/>
{fields.getIn(['username', 'errors'].first())}
<input
type="text"
onChange={(e) => form.setField('password', e.target.value)}
value={fields.getIn(['password', 'value'])}
/>
{fields.getIn(['password', 'errors'].first())}
<button onClick={() => form.submit()} />
</div>
);
export default connectForm(mapPropsToForm)(UserForm);
Loading async data into the form
import { Form, connectForm } from 'immutable-form';
const loadFormPromise = Promise.resolve({
username: 'someusername',
password: 'somepassword'
});
const userForm = new Form('userForm', {
fields: {
username: {
validate: [
username => username.trim().length === 0 && 'Username cannot be be empty',
],
},
password: {
validate: [
password => password.trim().length < 6 && 'Password must be longer than 6 characters',
],
},
},
})
.setLoad(form => loadFormPromise.then(({ username, password }) => {
form.setField('username', username);
form.setField('email', email);
form.saveInitialState();
}));
If using connectForm
the load promise will be called automatically in the component's lifecycle. To trigger a manual load, call form.load()
.
import { Form, connectForm } from 'immutable-form';
const Form = new Form('form', {}, {
logger: true,
addToFormCollection: true,
});