jaredpalmer / formik

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

Formik does not re-render when initialValues change #3591

Open liby opened 2 years ago

liby commented 2 years ago

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 macOS@12.4
KaiHotz commented 2 years ago

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.

liby commented 2 years ago

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.

nandorojo commented 2 years ago

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} />
liby commented 2 years ago

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.

nandorojo commented 2 years ago

Got it, looks like I misread the intent then.

liby commented 2 years ago

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

iamcrisb commented 1 year ago

hey @liby did you manage to find a workaround ?

liby commented 1 year ago

hey @liby did you manage to find a workaround ?

Not yet.

Helios69 commented 1 year ago

hey @liby did you manage to find a workaround ?

Not yet.

And now?)