Formik: Form is not dirtying when objects in the form change

Created on 3 Dec 2018  路  3Comments  路  Source: formium/formik

馃悰 Bug report

When a fields value is an object instead of an array / string, a change to the value will not dirty the form. This causes the form to require another item to be changed for the form to dirty, and in the case where isInitialValid is false, for the form to even be valid.

Current Behavior (in the demo)

Click the "Add my address" button
A new property should be added to testObj ( new value of myAddress: 222 Place)
The new property should be displayed below "Addresses"
The form should be dirtied and become valid. The submit button should be clickable.

Expected behavior

Clicked the "Add my address" button
A new property is added to testObj ( new value of myAddress: 222 Place)
The new property is displayed below "Addresses"
The form IS NOT dirtied and remains invalid. The submit button is not clickable.

Reproducible example

https://codesandbox.io/s/w6z5r0nmp8

The contrived example is the user is on a form and clicks a button to add their address to the form.
I left in the e-mail section so that you can see how the form should dirty / become valid.

Suggested solution(s)

The issue appears to be that when copying values to initial values (and back on reset), it is not being deep copied so the object is a reference copy. This means when the value is changed, the saved initial value is changed, making it look like the form still isn't dirty when the initial values are compared to the current values to check if it is dirty.

Additional context

I think the problem is manifesting on Formik.tsx:560, where the dirty value is calculated. I was able to get it working as expected by adding a cloneDeep whenever value was set to initialValue or initialValue was set to value.

Your environment

| Software | Version(s) |
| ---------------- | ---------- |
| Formik | 1.3.1 |
| React | 16.5.2 |
| TypeScript | 3.1.3 |
| Browser | Chrome 70.0.3538.110 |
| npm/Yarn | npm 6.4.1 |
| Operating System | MacOS 10.14.1 |

Formik Bug

Most helpful comment

This is not a bug as you setXXXX work like setState and must be immutable

All 3 comments

it seems using setFieldValue works just fine.
https://codesandbox.io/embed/625q5w7l0w

Had the same problem, and was using setFieldValue.
The gotcha is using the same reference to the values object :

not working

// directly updating the `values` object :
values.testObj.myAddress = "222 Place";
setFieldValue("testObj", values);

working

const newValues = {...values, myAddress: "222 Place"};
// or 
const newValues = Object.assign({}, values); // clone values
newValues.myAddress = "222 Place";

setFieldValue("testObj", newValues);

This is not a bug as you setXXXX work like setState and must be immutable

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jaredpalmer picture jaredpalmer  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

outaTiME picture outaTiME  路  3Comments

PeerHartmann picture PeerHartmann  路  3Comments

giulioambrogi picture giulioambrogi  路  3Comments