@hrgui/mobx-form-model
TypeScript icon, indicating that this package has built-in type declarations

0.7.3 • Public • Published

@hrgui/mobx-form-model

API is still unstable, and it may change wildly!

Yes, another attempt to bind mobx and forms, again.

I really like the API from formik but I also do like mobx. However, with formik, a lot of the logic ends up baked into the component, which makes it tied to React.

This is an attempt to move the logic and put it elsewhere, into MobX.

Who is this library for?

  • For those who don't want to mix React and busineess logic together.

Who is this library not for?

  • Those who don't use MobX and prefer plain-jane React. If that is the case, use formik

Example

https://codesandbox.io/s/2vonkqjjxp

import { observer } from "mobx-react";
import { observable } from "mobx";
import React from "react";
import {render} from 'react-dom';
import { Field, FormViewModel, ModelForm } from "@hrgui/mobx-form-model";
import yup from "yup";

class Person extends FormViewModel {
  validationSchema = yup.object().shape({
    firstName: yup.string().required(),
    lastName: yup.string().required()
  });

  validate = values => {
    const errors = {};
    if (!values.firstName) {
      errors.firstName = "You will need a firstname, buddy.";
    }

    return errors;
  };

  constructor() {
    super();

    this.initialValues = {
      firstName: "Mickey",
      lastName: "Mouse"
    };
  }

  onSubmit() {
    alert(this.values);
  }
}

const person = new Person();

@observer
export class PersonForm extends React.Component {
  @observable person = new Person();

  render() {
    return (
      <ModelForm model={this.person}>
        <Field name="firstName" />
        <Field name="lastName" />
        <Field name="address.city" />
        <input
          type="text"
          value={this.person.values.firstName}
          onChange={e => (this.person.values.firstName = e.target.value)}
        />
        <pre>values: {JSON.stringify(this.person.values, null, 2)}</pre>
        <pre>touched: {JSON.stringify(this.person.touched, null, 2)}</pre>
        <pre>errors: {JSON.stringify(this.person.errors, null, 2)}</pre>
        <button onClick={this.person.handleSubmit}>Save</button>
      </ModelForm>
    );
  }
}

render(<PersonForm />, document.getElementById("root"));

How it works

  1. A <ModelForm /> is really just a mobx-react <Provider /> that either provides a MobX form model or creates one.
  2. A <Field /> is an observer than injects the value provided by <Provider /> and supplies it the rendered component.
  3. When the <Field /> updates by user interaction, it calls the Model's handleChange method, which changes the Model's values observable.
  4. When the observable values changes, then it updates React accordingly.

API

See docs

FAQ

Why not just use formik, and sync it to MobX?

Synchronization of state between Formik and MobX is taboo, unless if you are a jedi. Doing so will have you ponder about the React lifecycle, or have very bad performance issues on forms.

Readme

Keywords

none

Package Sidebar

Install

npm i @hrgui/mobx-form-model

Weekly Downloads

0

Version

0.7.3

License

MIT

Unpacked Size

166 kB

Total Files

62

Last publish

Collaborators

  • hrgui