Awesome
reactive-mobx-form
Simple ans scalable form management library for React+MobX application. Under the hood it uses efficient MobX observable mechanizm, that allows tracking changes in form fields and rerender only things that have changed. This gives developer a feeling of working with 2-way data binding and reduces much boilerplate code needed to handle input events in 1-way data flow environment.
One of main features is "template based" approach - so you maintain your JSX structure only. This brings you to a situation that what is in your DOM is in your form values.
The library is inspired by Angular Reactive Forms and Redux Form. It has similar syntax to Redux Form, because of concept that are natural to React world. So if you previously had experience with it, it will be easy for you to start using reactive-mobx-form
. But still syntax is aimed to be clear for everyone.
Documentation
Examples can be found here.
Installation
npm install reactive-mobx-form
Usage
Step 1
Create and expose to all your application a formStore
via Provider from mobx-react
import { Provider } from 'mobx-react';
import { FormStore } from 'reactive-mobx-form';
const formStore = new FormStore();
render(
<Provider appStore={appStore} formStore={formStore}> // appStore - is any other store in your application
<App />
</Provider>,
document.getElementById('root')
);
Step 2
Create a form, look no more onChange
handlers on form fields. Just use Control
!
import { reactiveMobxForm, Control } from 'reactive-mobx-form';
class ContactForm extends React.Component {
render() {
const { submit } = this.props;
return (
<form onSubmit={submit}>
<div>
<label htmlFor="name">Name</label>
<Control name="name" component="input" type="text" />
</div>
<div>
<label htmlFor="age">Age</label>
<Control name="age" component="input" type="number"/>
</div>
<button type="submit">Submit</button>
</form>
);
}
}
const ContactFormReactive = reactiveMobxForm('contacts' [, formDefinition])(ContactForm); // 2nd parameter (formDefinition) is optional.
export default ContactFormReactive;
Detailed explanation of formDefinition object
Step 3
Use your form and enjoy, just don't forget to pass onSubmit
to it
import ContactFormReactive from './ContactForm';
export default Page extends React.Component {
handleSubmit(form) {
console.log(form)
}
render() {
<div>
<ContactFormReactive onSubmit={this.handleSubmit.bind(this)} />
</div>
}
}
This is how you may turn a simple form into a Reactive Mobx Form one. But reactive-mobx-form
gives you much more...
Capabilities
Its now possible:
- Render forms and submit them
- Validate fields, with powerful validatorjs library
- Render multi-level fields with
ControlSection
Component. Great for Component reuse. - Render filed, that contains array of data. Both singe item array, or array of objects with
ControlArray
. - Manage multi step forms, aka Wizard.
- Use
ComputedControl
component to render fields, which values are computed base of other form values - Localize your form/field names/error messages
Language Support
By default error messages are in English. But you can change them. reactive-mobx-form
provides you with interface for this. Under the hood it uses Validatorjs Language Support
Change language
In the index.js
or other entry point of your app.
import { configureValidator } from 'reactive-mobx-form';
configureValidator({
language: 'ru'
});
You can use MobX autorun function in order to execute this code each time app language change. Be careful as changing the language happens on Validator
class and effects all forms, even created before language switch.
Custom attribute names
When display error messages, you may want to modify how field name is displayed in error message. For example if field name is 'user.name' and this field is required. You'd like to see it in error message like 'The user name field is required.'. This may be done via setting custom attribute names(locally) or attribute names formatter function(globally). Same as language support, the functionality relays on Validatorjs Custom attribute names.
Change custom attribute names globally
In the index.js
or other entry point of your app.
import { configureValidator } from 'reactive-mobx-form';
configureValidator({
setAttributeFormatter: (attribute) => attribute.replace(/\./g, ' ')
});
setAttributeFormatter
property should be a function, that accepts 1 parameter field name, processes and returns it. In this example if we had a field name like 'user.name' it will be 'user name' in error message.
Change custom attribute names per form instance
Here we will benefit from other optional parameter to reactiveMobxForm
creation function called validator
.In place where you initialize form
const ContactFormReactive = reactiveMobxForm('contacts', {
validator: {
attributeNames: { // this option is available per form only
'users.name' : 'User Name'
}
// local setAttributeFormatter is not implemented yet
}
})(ContactForm)
attributeNames
is an object that maps field name to attribute in error message. So if we had a field name like 'user.name' it will be 'User NAme' in error message.
Custom Error Messages
With custom error messages it is possible to completely modify error message for some rule or combination of rule and field
const ContactFormReactive = reactiveMobxForm('contacts', {
validator: {
errorMessages: {
'required': 'You forgot to give a :attribute' // this format will be userd for all required fields
'required.email': 'Without an :attribute we can\'t reach you!' // format for required email field
}
}
})(ContactForm)
Note on versions
- 0.7.5 - is a stable version for usage in environments with any version of React but MobX < 4. (Map in MobX)
- 0.9.0 - is a stable version for React > 16.3, and MobX > 4(5) (mobx-react > 5.2.0). See changelog for updates. This version will be mainly developed.
Migration to 0.9.x
For most users migration will be just updating a version in package.json
. Make sure you are running React > 16.3.0. Also you can check commit for migration for docs site of reactive-mobx-form
Migration to 0.12.x
Remove destroyControlStateOnUnmount
parameter from form initialization. If you relied on a logic that control are brought back to form with initial values check here
Migration to 0.13.x
- Remove
destroyFormStateOnUnmount
parameter from form initialization. - If you relaid on mechanism that form state is preserved between full form unmounts - please use
keepState
property on yourForm
component. - You will have to rewrite your multi step forms via new API
Motivation
Working with forms was always a pain in web development. This library is an attempt to solve it for MobX and React users.
Goals:
- Zero configuration (I will not lie, you will still need some for not standard cases)
- Easy to learn and start with
- Preferable over own solutions (I hope it to be)
Dependency
reactive-mobx-forms depends directly on:
- validatorjs library for validation. It is small, effective and scalable.
reactive-mobx-forms peer dependencies are:
Know Issues
- When replacing
<A />
with<B />
,B.componentWillMount
now always happens beforeA.componentWillUnmount
. Previously,A.componentWillUnmount
could fire first in some cases. - Based on this. If you replace onereactiveMobXForm
with another having the same name. This will cause new form extend previous, and then form destroy. So just give your forms different names.