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.
Examples can be found here.
npm install reactive-mobx-form
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')
);
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](https://vict-shevchenko.github.io/reactive-mobx-form/#/api/reactiveMobxForm()) object
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...
Its now possible:
ControlSection
Component. Great for Component reuse.ControlArray
.ComputedControl
component to render fields, which values are computed base of other form valuesBy 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
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.
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.
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.
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.
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)
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
Remove destroyControlStateOnUnmount
parameter from form initialization. If you relied on a logic that control are brought back to form with initial values check here
destroyFormStateOnUnmount
parameter from form initialization.keepState
property on your Form
component. Working with forms was always a pain in web development. This library is an attempt to solve it for MobX and React users.
Goals:
reactive-mobx-forms depends directly on:
reactive-mobx-forms peer dependencies are:
<A />
with <B />
, B.componentWillMount
now always happens before A.componentWillUnmount
. Previously, A.componentWillUnmount
could fire first in some cases. - Based on this. If you replace one reactiveMobXForm
with another having the same name. This will cause new form extend previous, and then form destroy. So just give your forms different names.