formik icon indicating copy to clipboard operation
formik copied to clipboard

Formik does not re-render when initialValues change

Open liby opened this issue 2 years ago • 6 comments

Bug report

Current Behavior

When more than one form instance exists, changing the value by the A form triggers a change in the initial value of the B form that does not cause the B form to be re-render.

Expected behavior

The initial value is changed and the form is re-rendered.

Reproducible example

https://codesandbox.io/s/multiple-instance-values-overwrite-each-other-zm5wsx?file=/src/components/first-level-form.js

Suggested solution(s)

n/a

Additional context

Maybe I'm missing something. If my usage is wrong, please let me know. https://user-images.githubusercontent.com/38807139/175107045-2651e2e5-99c0-46e3-be65-1e650cfd878d.mp4

Your environment

Software Version(s)
Formik 2.2.9
React 18.2.0
TypeScript n/a
Browser Chrome Version 102.0.5005.115
npm/Yarn n/a
Operating System [email protected]

liby avatar Jun 22 '22 18:06 liby

I have the same issue but i suspect that it is not a re-rendering problem, instead it might have to do with the Automatic batching introduced in React 18. I guess that when enableReinitialize is set to true and the initial values are changed, the internal state of Formik is not flushed and set to the new initial values, instead the cached values of the previous state are returned.

My wild guess here is that Formik needs to opt out of the automatic batching by using flushSync() when the initial values get reinitialised.

KaiHotz avatar Jun 27 '22 04:06 KaiHotz

I have the same issue but i suspect that it is not a re-rendering problem, instead it might have to do with the Automatic batching introduced in React 18.

In fact, this issue exist in React 17 as well, which is easily reproducible.

liby avatar Jun 27 '22 05:06 liby

This isn't an issue. The initial part of the name indicates that this is intended. What is your use case for wanting to update it from outside? This would totally throw off the form.

If you want to delay setting initial values until some async data has loaded, I suggest using a loading spinner or something first:

const { data } = useUser()

if (!data) return <Loading />

return <EditUserForm initialValues={data} />

nandorojo avatar Jun 28 '22 16:06 nandorojo

What is your use case for wanting to update it from outside?

Have you seen me attach the file .mp4?

This isn't an issue. The initial part of the name indicates that this is intended.

In the screen recording, you can see that initialValues has changed, but values has not. This is not consistent with the documentation description.

liby avatar Jun 28 '22 18:06 liby

Got it, looks like I misread the intent then.

nandorojo avatar Jun 28 '22 18:06 nandorojo

Got it, looks like I misread the intent then.

I made another screen recording. It might be easier to understand than the previous one. You can watch it. https://user-images.githubusercontent.com/38807139/176254599-61e1e8cb-252c-479a-befa-8f9a76b59f28.mp4

liby avatar Jun 28 '22 18:06 liby

hey @liby did you manage to find a workaround ?

iamcrisb avatar Jan 02 '23 16:01 iamcrisb

hey @liby did you manage to find a workaround ?

Not yet.

liby avatar Jan 03 '23 01:01 liby

hey @liby did you manage to find a workaround ?

Not yet.

And now?)

Helios69 avatar Jan 23 '23 08:01 Helios69