Skip to content

fix(react-form): default selector to identity in Subscribe component#2065

Open
isaackaara wants to merge 3 commits intoTanStack:mainfrom
isaackaara:fix/subscribe-default-selector
Open

fix(react-form): default selector to identity in Subscribe component#2065
isaackaara wants to merge 3 commits intoTanStack:mainfrom
isaackaara:fix/subscribe-default-selector

Conversation

@isaackaara
Copy link

When <form.Subscribe> is rendered without a selector prop, it crashes at runtime:

TypeError: selector is not a function

The types already mark selector as optional (selector?), so the runtime should handle the missing case. This adds a default identity function (state) => state for the selector parameter in both LocalSubscribe implementations (useForm and useFieldGroup).

Before (crashes):

<form.Subscribe>
  {(state) => <button disabled={state.isSubmitting}>Save</button>}
</form.Subscribe>

After (works, returns full form state):

<form.Subscribe>
  {(state) => <button disabled={state.isSubmitting}>Save</button>}
</form.Subscribe>

Fixes #2063

When <form.Subscribe> is rendered without a selector prop, it crashes
at runtime because useStore receives undefined as the selector:

  TypeError: selector is not a function

The types already mark selector as optional, so the runtime behavior
should match. This adds a default identity function ((state) => state)
for the selector parameter in both LocalSubscribe implementations
(useForm and useFieldGroup).

Fixes TanStack#2063
@changeset-bot
Copy link

changeset-bot bot commented Mar 6, 2026

⚠️ No Changeset found

Latest commit: e2e3aa7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@nx-cloud
Copy link

nx-cloud bot commented Mar 6, 2026

View your CI Pipeline Execution ↗ for commit e2e3aa7

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

☁️ Nx Cloud last updated this comment at 2026-03-06 08:56:23 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 6, 2026

More templates

@tanstack/angular-form

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

@tanstack/form-core

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

@tanstack/form-devtools

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

@tanstack/lit-form

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

@tanstack/react-form

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

@tanstack/react-form-devtools

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

@tanstack/react-form-nextjs

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

@tanstack/react-form-remix

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

@tanstack/react-form-start

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

@tanstack/solid-form

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

@tanstack/solid-form-devtools

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

@tanstack/svelte-form

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

@tanstack/vue-form

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

commit: 581ae99

@sentry
Copy link

sentry bot commented Mar 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.50%. Comparing base (6892ed0) to head (e2e3aa7).
⚠️ Report is 146 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2065       +/-   ##
===========================================
- Coverage   90.35%   56.50%   -33.85%     
===========================================
  Files          38       18       -20     
  Lines        1752      246     -1506     
  Branches      444       47      -397     
===========================================
- Hits         1583      139     -1444     
+ Misses        149       92       -57     
+ Partials       20       15        -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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

@LeCarbonator
Copy link
Contributor

dw about the coverage failing, as long as the lines you changed are covered.

I'll review in a bit. Thanks!

Copy link
Contributor

@LeCarbonator LeCarbonator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! As far as runtime changes go, this is ready to merge. I'm not convinced by the type change, and since type changes are not covered by semantic versioning, those are fine to keep.

Curious to hear your thoughts.

children,
}: PropsWithChildren<{
lens: AnyFieldGroupApi
selector: (state: FieldGroupState<any>) => FieldGroupState<any>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned that "the types already mark the selector as optional", but it wasn't marked here.

A subscription without a selector (or an identity selector) makes no sense, so we shouldn't encourage it. For the sake of semver, the identity function fallback should stay, but the types should enforce that a selector is required.

expect(button).toBeInTheDocument()
})

it('should render FieldGroup Subscribe without selector (default identity)', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, if the selector will be marked as required, these tests would type error.

Adjust the title to mention the related GH issue or that this is for semver.

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.

<form.Subscribe> allows missing selector in types, but crashes at runtime (selector is not a function)

2 participants