jaredpalmer / formik

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

Replacing an object in an array with one with empty properties leaves the visual state of the previous object. #3866

Closed adjenks closed 10 months ago

adjenks commented 1 year ago

Bug report

Current Behavior

When swapping or moving an object in an array, if an object that has undefined or null values, it shows up in the interface as though it has defined values. image

Expected behavior

The fields should show up blank instead of having a ghost of the previous property values.

Reproducible example

https://codesandbox.io/s/formik-array-swap-ghosting-w7882k

Step 1: Type in top box Step 2: Click "Move down" Step 3: Observe data and interface inconsistency.

Suggested solution(s)

It needs to refresh the visual state of the objects at the array indices.

Additional context

I really need this to work. Any suggestions on how to work around it?

Your environment

As in the demo: image

adjenks commented 1 year ago

Additionally, I don't have it shown in this example, but in my project I'm using Yup to validate my form, and the error object stays up to date when moving the objects. So somehow the error validation object is rendered more in sync than the actual object.

adjenks commented 1 year ago

It works if you blank the whole array and then pause for a millisecond and then replace it:

                      onClick={() =>{
                        // arrayHelpers.swap(i, i + 1)
                        var newArray = JSON.parse(JSON.stringify(form.values.mainarray))
                        newArray[i] = newArray.splice(i+1,1,newArray[i])[0]
                        form.setFieldValue('mainarray',[])
                        setTimeout(()=>form.setFieldValue('mainarray',newArray),1)
                      }}

I commented that replacing the whole array doesn't work, but it does work if you add a setTimeout so that React won't group the changes together which would ignore the empty array.

darielkurt commented 1 year ago

@adjenks This also happens when I use arrayHelpers.remove(index), I'll try your workaround

vennilamahalingam commented 1 year ago

Hi,

I am willing to work on this issue !

Thanks.

mfaheemakhtar commented 10 months ago

You guys need to learn about mutations and the correct way of rendering a list in React.

Your code on codesandbox is missing key prop on fieldset. Using index as key won't work either.

I guess the Field is an uncontrolled input, otherwise it would have worked anyway.

https://react.dev/learn/rendering-lists

adjenks commented 10 months ago

Well then... He's not wrong. Don't forget to use keys.