foxhound87 / mobx-react-form

Reactive MobX Form State Management
https://foxhound87.github.io/mobx-react-form
MIT License
1.09k stars 129 forks source link

Bug: Nested value of null marks form dirty on init #585

Closed benjamingeorge closed 1 year ago

benjamingeorge commented 3 years ago

I recently updated to the latest version of this library and noticed a new bug where my form isDirty = true on initialization. I set values on my form that come back from an API response. Sometimes that value object has a nested object where some properties are null. When they are, MobxReactForm marks the form dirty on form initialization. But if those nested values are any other type (string, boolean, number) the form is not marked as dirty. It seems to be only a problem with nested values of type null. Top level values of null do not seem to be a problem, only nested ones.

Below is an example of the bug. See in the values object, the account: { id: null } causes the form to be isDirty = true on initialization which is a bug. If you change it to account: { id: "123" } or even account: { id: "" } , we get isDirty = false on initialization which is correct .

import React, { useState } from "react";
import { observer } from "mobx-react";
import dvr from "mobx-react-form/lib/validators/DVR";
import validatorjs from "validatorjs";
import MobxReactForm from "mobx-react-form";

const plugins = {
    dvr: dvr(validatorjs)
};

const hooks = {
    onSuccess(form) {
        alert("Form is valid! Send the request here.");
        // get field values
        console.log("Form Values!", form.values());
    },
    onError(form) {
        alert("Form has errors!");
        // get all form errors
        console.log("All form errors", form.errors());
    }
};

const schema = {
    fields: ["email"],
    labels: { email: "Email" },
    rules: { email: "required|email|string|between:5,25" },
    values: { email: "myemail@apple.com", account: { id: null, name: "John" } }
};

const Form = observer(({ form }) => {
    console.log(form.isDirty); // true
    return (
        <form>
            <label htmlFor={form.$("email").id}>{form.$("email").label}</label>
            <input {...form.$("email").bind()} />

            <button type="submit" onClick={form.onSubmit}>
                Submit
            </button>
            <button type="button" onClick={form.onClear}>
                Clear
            </button>
            <button type="button" onClick={form.onReset}>
                Reset
            </button>

            <p>{form.error}</p>
        </form>
    );
});

export default () => {
    const [form] = useState(() => new MobxReactForm(schema, { plugins, hooks }));
    return <Form form={form} />;
};
GorynychDragon commented 3 years ago

Have the same problem. Does anyone have any thoughts on it?

foxhound87 commented 1 year ago

I noticed you forgot to define the account field in then fields array. I tested this with the correct field definition and worked (without null values).

foxhound87 commented 1 year ago

Related #531

github-actions[bot] commented 1 year ago

:tada: This issue has been resolved in version 5.5.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: