jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
34.02k stars 2.79k forks source link

Touched state isn't correct when dealing with array values #1712

Open micheleberetta98 opened 5 years ago

micheleberetta98 commented 5 years ago

🐛 Bug report

Current Behavior

I have a multi-select field in Formik, which needs to be an array. The touched state of this fields results in an empty array instead of true.

EDIT: This happens when submitting.

Expected behavior

The touched state of the array field should be a boolean.

Suggested solution(s)

Additional context

I have found this related issue https://github.com/jaredpalmer/formik/issues/793#issuecomment-492523947, but it is closed for inactivity, and the workaround suggested is not applicable for us.

Your environment

Software Version(s)
Formik 1.5.8
React 16.8.6
TypeScript not used
Browser Chrome 75
npm/Yarn yarn 1.16.0
Operating System Windows 10
bricejar commented 5 years ago

Hi,

Can you reproduce the error in a codesanbox please ?

micheleberetta98 commented 5 years ago

Here you go https://codesandbox.io/s/relaxed-shape-67lf8

filippoitaliano commented 5 years ago

I have the same issue here. I have some array values in my form. They represent the choices taken by the user in a multi-selection field. I handle them as traditional values.

const initialValues = {
  normalValue: '',
  nullableValue: null,
  choices: ['defaultChoice'], // < this one is a multi-select `value`
};

The relative touched flag is an empty array instead the expected true boolean when I touch the value.

Handling arrays values is an intended Formik usage? Is this a bug of the touched logic or I'm missing something crucial?

micheleberetta98 commented 5 years ago

Is there anything new about this?

micheleberetta98 commented 5 years ago

Is this dead?

hiei23 commented 5 years ago

I'm getting the same error and I think this PR fixes #1134

ivoberger commented 5 years ago

How's the state on this? I have the same issue.

thexpand commented 4 years ago

I'm experiencing the same problem. I can't figure out why... and it's only on submitting the form.

johnrom commented 4 years ago

Confirmed issue in latest as well. It only occurs when submitting the form, normal handleBlur works perfectly.

repro

thexpand commented 4 years ago

I think it's related to this issue here - https://github.com/jaredpalmer/formik/issues/1942 Not sure if it will be solved at all.

kanonirbrest commented 2 years ago

Hey guys I found the source of this problem. When you push new arguments to array you should use for example (Use the JSON.stringify() and JSON.parse()) to create copy of array and object (that you are going to push) after set it to formik. In case if you will create const default = {name: 'name'}; and then do formik.setFieldValue('path', [default, ...formik.values.path]) 2 or 3 times, the touch will ignore last copy. As i understand there are incorrect comparison for objects the has the same source. Hope it will help you. For me JSON.stringify() and JSON.parse()) resolved all problems with validation. Let me know whether it helps you.

Wellers0n commented 1 year ago

I solved this problem like this

Screenshot 2023-01-11 at 22 25 00

ashwth commented 1 year ago

In my case, I had arrays of object and in that object had another array for multiselect and i forgot to insert array property into the object.

before

arrayHelpers.insert(values.clientSubscriptions?.length ?? 0, {
                                                              id: '',
                                                              marketId: '',
                                                              startWeek: '',
                                                              endWeek: ''
                                                          }) 

after inserting with empty array it started to work

after

arrayHelpers.insert(values.clientSubscriptions?.length ?? 0, {
                                                                 id: '',
                                                                 marketId: '',
                                                                startWeek: '',
                                                                endWeek: '',
                                                                channelIds: [],
                                                               })