When you render `Field` conditionally first rendered field will override all next rendered fields
Describe the bug
Use case:
I want to render different Field components according to some condition of form state.values.
It used to work in previous versions (0.21=<).
Your minimal, reproducible example
https://stackblitz.com/edit/vitejs-vite-dvwuju?file=src%2FApp.jsx
Steps to reproduce
- go to https://stackblitz.com/edit/vitejs-vite-dvwuju?file=src%2FApp.jsx
- fill input
- click checkbox
- check values of form
Expected behavior
I expected that values firstField value will dissapear from state when you uncheck checkbox and secondField value will be stored in state.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
Arc browser
TanStack Form adapter
react-form
TanStack Form version
v0.25.1
TypeScript version
=v5.4.5
Additional context
No response
upd: You may fix it if you render it under different Subscribe components. But it feels like a bug...
You can also "fix" it by applying a key prop to each of the <Field> instances that would occupy the same position in the tree, (e.g. <Field key="first" name="firstField">).
Because of that, I think the problem is that the <Field> component and useField state not "noticing" when the name prop has changed.
Here, we see that the fieldApi instance is created once with the initial name value, and then kept in state.
https://github.com/TanStack/form/blob/2bebfd5214c4cdfbf6feacb7b1e25a6825957062/packages/react-form/src/useField.tsx#L68-L81
The value of this.name is only set when a new instance is constructed:
https://github.com/TanStack/form/blob/2bebfd5214c4cdfbf6feacb7b1e25a6825957062/packages/form-core/src/FieldApi.ts#L429-L442
And the field's getValue and setValue functions use the initial this.name value:
https://github.com/TanStack/form/blob/2bebfd5214c4cdfbf6feacb7b1e25a6825957062/packages/form-core/src/FieldApi.ts#L597-L611
In the update function, we can see that it uses the opt.name value to get the correct default value, but doesn't update the stored this.name to be the new value of opts.name; so getValue/setValue continue to use the (initial, now incorrect) value.
https://github.com/TanStack/form/blob/2bebfd5214c4cdfbf6feacb7b1e25a6825957062/packages/form-core/src/FieldApi.ts#L564-L595
@BenJenkinson Yep, everything works as you explained. Thank you for explanation. I haven't tried to dive into implementation. In my codebase I've fixed it with two Subscribe blocks.
For me it looks like unhandled name property of opts in update.
I think it's worth fixing that. I may do a PR on that. Either it's worth reflecting in the doc. @crutchcorn what do you think? Do you mind if I fix it?
This issue should be fixed by https://github.com/TanStack/form/pull/1097#.
See the fixed reproducible example here: https://stackblitz.com/edit/vitejs-vite-y5jdu3qf?file=src%2FApp.jsx