Skip to content

fix(react-form,preact-form): prevent unnecessary FormGroup child re-renders - #2380

Open
dikshit-n wants to merge 1 commit into
TanStack:mainfrom
dikshit-n:fix/form-group-rerender-issue-2377
Open

fix(react-form,preact-form): prevent unnecessary FormGroup child re-renders#2380
dikshit-n wants to merge 1 commit into
TanStack:mainfrom
dikshit-n:fix/form-group-rerender-issue-2377

Conversation

@dikshit-n

@dikshit-n dikshit-n commented Sep 11, 2026

Copy link
Copy Markdown

Summary

When a field value inside a FormGroup changes, all child components in that FormGroup were re-rendering — even components that had no dependency on the changed field. This is a significant performance regression for forms with many fields in a group.

Root Cause

useFormGroup subscribed to the FormGroup's own store with the selector (state) => state.value. This selector returns the entire group value object, which gets a new reference every time any field in the group changes. Because the selector fires on every group-level store update, the useMemo that constructs extendedFieldApi always recomputes, causing a full re-render of all children.

Fix

Subscribe to the form's baseStore with a path-based selector that reads only the specific group value at opts.name. Using getBy(state.values, opts.name) means:

  • Changes to fields inside this group → selector returns a new reference → hook re-renders (correct)
  • Changes to fields in other groups → selector returns the same value → no re-render (correct)

This mirrors the existing optimization pattern used for array-mode fields in useField.

Changes

  • packages/react-form/src/useFormGroup.tsx: Changed useSelector to read from formGroupApi.form.baseStore with a getBy(state.values, opts.name) selector
  • packages/preact-form/src/useFormGroup.tsx: Same fix for the Preact adapter
  • packages/react-form/tests/useFormGroup.test.tsx: Added regression test

Testing

A new unit test (should not re-render sibling field components when a field value changes) verifies that changing a field in step2 does not trigger a re-render of a field inside the step1 FormGroup.

Closes #2377

Summary by CodeRabbit

  • Performance Improvements

    • Form groups now update only when fields within the group change, reducing unnecessary re-renders caused by changes in sibling groups.
  • Bug Fixes

    • Prevented unrelated field components from re-rendering when values change in a different form group.
  • Tests

    • Added regression coverage to verify that sibling form groups remain unaffected by unrelated field updates.

…enders (TanStack#2377)

Subscribe to the form's baseStore with a path-based selector instead of
the FormGroup's own store value. This ensures useFormGroup only
re-renders when a field *inside this specific group* changes, not when
any sibling group's value changes.

Issue: changing a field value in a FormGroup caused ALL child components
in the group to re-render, even when those components didn't read the
changed field.
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 80d8a078-69ca-40fd-8388-152f7583977b

📥 Commits

Reviewing files that changed from the base of the PR and between 57a855b and b455fb7.

📒 Files selected for processing (3)
  • packages/preact-form/src/useFormGroup.tsx
  • packages/react-form/src/useFormGroup.tsx
  • packages/react-form/tests/useFormGroup.test.tsx

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

useFormGroup in the React and Preact adapters now selects group values from the form base store by path. A regression test verifies that changing a field in one group does not re-render a field in another group.

Changes

FormGroup rendering optimization

Layer / File(s) Summary
Path-based FormGroup subscriptions and regression coverage
packages/preact-form/src/useFormGroup.tsx, packages/react-form/src/useFormGroup.tsx, packages/react-form/tests/useFormGroup.test.tsx
Both adapters use getBy(state.values, opts.name) with the form baseStore. The regression test verifies that a field in step1 does not re-render when a field in step2 changes.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to b455f

The FormGroup subscription change is covered for sibling-group isolation in React and applies the same path-based selector in both adapters.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes address unnecessary re-renders caused by fields in sibling FormGroups [#2377]. However, the selector still returns the entire current group value, so changing one field within the same For… Update the FormGroup subscription or child field subscription model so a field change does not re-render unrelated children within the same FormGroup. Add a regression test that changes one field and verifies unrelated fields in the same Fo…
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the React and Preact FormGroup performance fix. It is concise and matches the main changes.
Description check ✅ Passed The description provides a detailed summary, root cause, fix, affected files, and testing information. It does not use the template headings or include the checklist and release-impact sections, but t…
Out of Scope Changes check ✅ Passed The changes are limited to the React and Preact useFormGroup implementations and a related React regression test. All changes support the linked FormGroup re-rendering objective.
Full details: Linked Issues check

Explanation

The changes address unnecessary re-renders caused by fields in sibling FormGroups [#2377]. However, the selector still returns the entire current group value, so changing one field within the same FormGroup can still re-render all children in that group. This does not fully satisfy the issue’s requirement to isolate re-renders to the affected field or dependent components.

Resolution

Update the FormGroup subscription or child field subscription model so a field change does not re-render unrelated children within the same FormGroup. Add a regression test that changes one field and verifies unrelated fields in the same FormGroup do not re-render. [#2377]

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Field value change in FormGroup causes all fields in FormGroup to re-render

1 participant