form
form copied to clipboard
'Cannot convert undefined or null to object' when rendering field conditionally with React.StrictMode
Describe the bug
If you conditionally render a field with React.StrictMode activated, the library crashes. When disabling React.StrictMode, everything works fine.
Your minimal, reproducible example
https://codesandbox.io/p/devbox/tanstack-form-conditional-field-kfljkr
Steps to reproduce
- Click "Submit" - You will get a error "A first name is required"
- Click "Hide field" - This will remove First Name field
- Click "Submit" again - The app will crash
Expected behavior
The form should submit without crashing.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
OS: MacOS Browser: Chrome
Tanstack Form adapter
react-form
TanStack Form version
v0.13.3
TypeScript version
v5.2.2
Additional context
No response
Wow! Great catch - we'll tackle this ASAP
Yes, it took some time to find the problem 😀 Thank you for your support!
I think it has something to do with issue #495 . The crash point is also
state.meta.errors = Object.values(state.meta.errorMap).filter( (val) => val !== void 0 ); because errorMap is not defined.
[!NOTE] Edit: You don't have to read this long comment, I created a draft PR with a non-prod-ready solution to illustrate my point (I also explain my thoughts better there): https://github.com/TanStack/form/pull/576
Original comment:
I don't know if I add anything valuable here, but to me, it looks like a new field instance (in form.getFieldInfo('firstName').instances) is created every time the firstName field is rendered, but deleted only every second time it's destroyed. I suspect that this is because the 1st runs are always triggered by <StrictMode> and there's a piece of logic in the useIsomorphicEffectOnce() hook, that prevents the cleanup function from being executed for "dummy React cycles" (this hook is used in useField()):
I think this is what leads to the number of Error messages growing every time we toggle the visibility of the firstName field in the CodeSandbox from the description:
https://github.com/TanStack/form/assets/43729152/ba3523ce-c79e-4cbb-ae18-8d38cb31bb63
Locally I tried to remove the redundant field instances manually in the packages/form-core/src/FieldApi.ts file (lines 402-414), and it seemed to solve the issue, so I could be on the right track here:
return () => {
const preserveValue = this.options.preserveValue
unsubscribe()
if (!preserveValue) {
delete info.instances[this.uid - 1] <-- this is the new line (NOT a real solution)
delete info.instances[this.uid]
this.form.deleteField(this.name)
}
if (!Object.keys(info.instances).length && !preserveValue) {
delete this.form.fieldInfo[this.name]
}
}
https://github.com/TanStack/form/assets/43729152/427b2acf-05e3-4b7a-a302-b6b7f5cf6c3c
Honestly, I'm still very new to the internals of tanstack/form, so I'm just relying on my instincts here... @crutchcorn Does this make any sense? If yes, should I pick it up?
This required a lot of investigation and internal discussion - thanks for your patience everyone!
Should now be fixed in TanStack Form 0.13.7 🎉