formik icon indicating copy to clipboard operation
formik copied to clipboard

Wrong dirty state for checkbox group

Open aivarasbiliunas opened this issue 3 years ago • 4 comments

Bug report

Scenario: Have a group of checkboxes { toggles: [A, B, C, D] } with initial values { toggles: [B, C] }. When unchecking B and then checking again dirty state would still be true while it suppose to be false.

Current Behavior

Clicking on first pre-selected checkbox to uncheck it and when clicking again to check it sets dirty state to true.

Expected behavior

Clicking on pre-selected checkbox to uncheck it and when check it again (returning to initial values) would set dirty state to false.

Reproducible example

Example https://codesandbox.io/s/beautiful-williamson-5rt3w

Suggested solution(s)

This is has to do with how field with type checkbox onChange behaves. It always adds new value to end of array instead of position from where it was removed. Therefore Initial state: [B, C] dirty state after unchecking: [C] dirty state after checking again: [C, B] One of solutions would be when adding new value to array sort it first.

Your environment

Software Version(s)
Formik 2.1.4
React 16.14.0
TypeScript 4.2.3
Browser
npm/Yarn
Operating System

aivarasbiliunas avatar May 26 '21 11:05 aivarasbiliunas

From formik doc

Returns true if values are not deeply equal from initial values, false otherwise. dirty is a readonly computed property and should not be mutated directly

Dirty set to true if initial value and value are not equal.. something like JSON.stringify(initalValue) === JSON.stringify(value)

dreamerchandra avatar Jun 02 '21 15:06 dreamerchandra

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 60 days

github-actions[bot] avatar Jul 03 '21 00:07 github-actions[bot]

Experiencing the same issue here, please fix it. Sorting the array as @aivarasbiliunas suggested could resolve it.

nivanis91 avatar Sep 27 '21 16:09 nivanis91

Another solution can be to write your own dirty logic by comparing the initial values with the current Form values. You can convert them to Sets and use _.isEqual. The Set will ignore the order and you don't need to sort your arrays.

nat0shi avatar Jun 17 '22 12:06 nat0shi