From 45ed204abe8ca59e1753c2fead75898908f031cf Mon Sep 17 00:00:00 2001 From: Scott Cooper Date: Mon, 24 Aug 2026 10:12:59 -0700 Subject: [PATCH 1/3] perf(react-form): Use one subscription per Field Each React Field subscribed to the same atom once for value and again for meta. The field atom already preserves state identity when neither changes, so one whole-state subscription has the same render behavior. Co-Authored-By: OpenAI Codex --- .../react-form/src/ReactForm/fieldSubscriptions.lib.ts | 8 +++----- packages/react-form/tests/FormGroup.spec.tsx | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts b/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts index 760b3575e1..8c9f120da4 100644 --- a/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts +++ b/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts @@ -5,14 +5,12 @@ import type { AnyInternalFieldApi } from '@tanstack/form-core/internals' export function useValueFieldSubscription( fieldApi: AnyInternalFieldApi, ): AnyInternalFieldApi { - const value = useSelector(fieldApi.atom, (state) => state.value) - const meta = useSelector(fieldApi.atom, (state) => state.meta) + const state = useSelector(fieldApi.atom) return useMemo(() => { - void meta - void value + void state return Object.create(fieldApi) - }, [fieldApi, meta, value]) + }, [fieldApi, state]) } export function useArrayFieldSubscription( diff --git a/packages/react-form/tests/FormGroup.spec.tsx b/packages/react-form/tests/FormGroup.spec.tsx index c040db8d9e..62dd054c29 100644 --- a/packages/react-form/tests/FormGroup.spec.tsx +++ b/packages/react-form/tests/FormGroup.spec.tsx @@ -118,7 +118,7 @@ describe('FormGroup', () => { expect(getByTestId('app-field-name')).toHaveTextContent('guestDetails.name') }) - it('uses the AppForm field provider subscription for field context', async () => { + it('uses one AppForm field provider subscription for field context', async () => { const subscribe = vi.fn() const unsubscribe = vi.fn() const instrumentedAtoms = new WeakSet() @@ -169,7 +169,7 @@ describe('FormGroup', () => { await vi.waitFor(() => { expect(subscribe.mock.calls.length - unsubscribe.mock.calls.length).toBe( - 2, + 1, ) }) From 2257d3df1fe9f2423cc5332daca6f1ee5902c5af Mon Sep 17 00:00:00 2001 From: LeCarbonator <18158911+LeCarbonator@users.noreply.github.com> Date: Tue, 1 Sep 2026 09:56:12 +0200 Subject: [PATCH 2/3] chore: Update packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts --- packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts b/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts index 8c9f120da4..ee22fa6b1d 100644 --- a/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts +++ b/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts @@ -5,7 +5,7 @@ import type { AnyInternalFieldApi } from '@tanstack/form-core/internals' export function useValueFieldSubscription( fieldApi: AnyInternalFieldApi, ): AnyInternalFieldApi { - const state = useSelector(fieldApi.atom) + const state = useSelector(fieldApi.atom, state => state) return useMemo(() => { void state From 4fde2fbf3cb1902573d735496d20e5ac63e16420 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 07:57:35 +0000 Subject: [PATCH 3/3] ci: apply automated fixes and generate docs --- packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts b/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts index ee22fa6b1d..d67491fedf 100644 --- a/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts +++ b/packages/react-form/src/ReactForm/fieldSubscriptions.lib.ts @@ -5,7 +5,7 @@ import type { AnyInternalFieldApi } from '@tanstack/form-core/internals' export function useValueFieldSubscription( fieldApi: AnyInternalFieldApi, ): AnyInternalFieldApi { - const state = useSelector(fieldApi.atom, state => state) + const state = useSelector(fieldApi.atom, (state) => state) return useMemo(() => { void state