form icon indicating copy to clipboard operation
form copied to clipboard

fix: sync validation errors for delayed-mounted fields

Open jiji-hoon96 opened this issue 4 months ago • 13 comments

Fixes validation errors not appearing on fields that mount after form initialization

Problem

When fields are mounted after the form's initial validation runs, validation errors from form-level validators (like [onMount]) are not displayed on these delayed fields, leading to inconsistent validation UX.

Solution

  • FormApi: Store all field errors (including for unmounted fields) in _allFieldErrors state
  • FieldApi: Sync existing errors from form state when fields mount, marking them as originating from form validation

Changes

  • Added _allFieldErrors property to BaseFormState to persist validation errors for all fields
  • Modified validateSync to store field errors for both mounted and unmounted fields
  • Enhanced FieldApi.mount() to sync existing errors from form state on field mount
  • Added comprehensive tests covering delayed mount, multiple fields, and remount scenarios

Closes #1630

jiji-hoon96 avatar Aug 14 '25 06:08 jiji-hoon96

👀

brandonleichty avatar Aug 17 '25 18:08 brandonleichty

@LeCarbonator I thought this issue needed to be resolved promptly, and I'm curious to hear your thoughts on the matter.

jiji-hoon96 avatar Sep 02 '25 07:09 jiji-hoon96

I'm also quite curious about this one. I've had to use hidden in all of my forms, rather than conditional rendering. Which doesn't feel great—especially for future readers of the code.

brandonleichty avatar Sep 02 '25 16:09 brandonleichty

View your CI Pipeline Execution ↗ for commit 23bfa578ed45ee64dc2544aa74fa988ddce95c4c

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 57s View ↗
nx run-many --target=build --exclude=examples/** ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-18 10:09:17 UTC

nx-cloud[bot] avatar Sep 02 '25 16:09 nx-cloud[bot]

I'm just not sure if this is the way to go about it. I've been tinkering behind the scenes to see what truly causes this, but I suppose I should focus more on it so it can get fixed

LeCarbonator avatar Sep 02 '25 16:09 LeCarbonator

More templates

@tanstack/angular-form

npm i https://pkg.pr.new/@tanstack/angular-form@1691
@tanstack/form-core

npm i https://pkg.pr.new/@tanstack/form-core@1691
@tanstack/form-devtools

npm i https://pkg.pr.new/@tanstack/form-devtools@1691
@tanstack/lit-form

npm i https://pkg.pr.new/@tanstack/lit-form@1691
@tanstack/react-form

npm i https://pkg.pr.new/@tanstack/react-form@1691
@tanstack/react-form-devtools

npm i https://pkg.pr.new/@tanstack/react-form-devtools@1691
@tanstack/react-form-nextjs

npm i https://pkg.pr.new/@tanstack/react-form-nextjs@1691
@tanstack/react-form-remix

npm i https://pkg.pr.new/@tanstack/react-form-remix@1691
@tanstack/react-form-start

npm i https://pkg.pr.new/@tanstack/react-form-start@1691
@tanstack/solid-form

npm i https://pkg.pr.new/@tanstack/solid-form@1691
@tanstack/solid-form-devtools

npm i https://pkg.pr.new/@tanstack/solid-form-devtools@1691
@tanstack/svelte-form

npm i https://pkg.pr.new/@tanstack/svelte-form@1691
@tanstack/vue-form

npm i https://pkg.pr.new/@tanstack/vue-form@1691

commit: 23bfa57

pkg-pr-new[bot] avatar Sep 02 '25 16:09 pkg-pr-new[bot]

Codecov Report

:white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 89.43%. Comparing base (6892ed0) to head (23bfa57). :warning: Report is 102 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1691      +/-   ##
==========================================
- Coverage   90.35%   89.43%   -0.93%     
==========================================
  Files          38       48      +10     
  Lines        1752     1940     +188     
  Branches      444      487      +43     
==========================================
+ Hits         1583     1735     +152     
- Misses        149      184      +35     
- Partials       20       21       +1     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Sep 02 '25 16:09 codecov[bot]

I'm not entirely sure why the delayed-mounted field isn't receiving form validation either.

While my proposed method could resolve it, errors exist in both fieldMeta and _allFieldErrors. This raises concerns about duplicate states and memory overhead issues, as it would persistently store errors for all unmounted fields.

If you have any ideas, please share them so we can explore them together.

I have three potential approaches in mind

  1. Event-driven approach: Re-trigger form validation when the field mounts, re-executing the validation results only for this field.
  2. Store validation results as a function and evaluate them when needed.
  3. Subscribe to the form's validation state when the field mounts.

jiji-hoon96 avatar Sep 03 '25 00:09 jiji-hoon96

The issue is that while mapping form validators to respective fields, it only iterates through the existing record of (previously registered) fields. Ideally, it should have the following behaviour:

  • If a field error does not have an entry in the fieldInfo record, create one
  • If deleteField or removeValue is called, it should remove that entry

LeCarbonator avatar Sep 08 '25 13:09 LeCarbonator

@LeCarbonator FormApi has been improved with a comprehensive error-handling approach that includes all field errors, and features have been added to automatically generate fieldInfo and prevent memory leaks in the deleteField method.

jiji-hoon96 avatar Sep 10 '25 04:09 jiji-hoon96

@jiji-hoon96 does this mean the issue should be resolved?

brandonleichty avatar Sep 20 '25 00:09 brandonleichty

@brandonleichty Yes!

jiji-hoon96 avatar Sep 20 '25 00:09 jiji-hoon96

🦋 Changeset detected

Latest commit: 23bfa578ed45ee64dc2544aa74fa988ddce95c4c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@tanstack/form-core Patch
@tanstack/angular-form Patch
@tanstack/form-devtools Patch
@tanstack/lit-form Patch
@tanstack/react-form Patch
@tanstack/solid-form Patch
@tanstack/svelte-form Patch
@tanstack/vue-form Patch
@tanstack/react-form-devtools Patch
@tanstack/solid-form-devtools Patch
@tanstack/react-form-nextjs Patch
@tanstack/react-form-remix Patch
@tanstack/react-form-start Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Sep 20 '25 08:09 changeset-bot[bot]