diff --git a/packages/react-form/src/useFieldGroup.tsx b/packages/react-form/src/useFieldGroup.tsx index 063187c52..a3e05df9f 100644 --- a/packages/react-form/src/useFieldGroup.tsx +++ b/packages/react-form/src/useFieldGroup.tsx @@ -23,11 +23,11 @@ import type { LensFieldComponent } from './useField' function LocalSubscribe({ lens, - selector, + selector = (state) => state, children, }: PropsWithChildren<{ lens: AnyFieldGroupApi - selector: (state: FieldGroupState) => FieldGroupState + selector?: (state: FieldGroupState) => FieldGroupState }>): ReturnType { const data = useStore(lens.store, selector) diff --git a/packages/react-form/src/useForm.tsx b/packages/react-form/src/useForm.tsx index 2d75f0d77..d50651c02 100644 --- a/packages/react-form/src/useForm.tsx +++ b/packages/react-form/src/useForm.tsx @@ -139,11 +139,11 @@ export type ReactFormExtendedApi< function LocalSubscribe({ form, - selector, + selector = (state) => state, children, }: PropsWithChildren<{ form: AnyFormApi - selector: (state: AnyFormState) => AnyFormState + selector?: (state: AnyFormState) => AnyFormState }>): ReturnType { const data = useStore(form.store, selector) diff --git a/packages/react-form/tests/createFormHook.test.tsx b/packages/react-form/tests/createFormHook.test.tsx index 57df138e5..273746d0b 100644 --- a/packages/react-form/tests/createFormHook.test.tsx +++ b/packages/react-form/tests/createFormHook.test.tsx @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { render } from '@testing-library/react' +import { render, waitFor } from '@testing-library/react' import { formOptions } from '@tanstack/form-core' import userEvent from '@testing-library/user-event' import { createFormHook, createFormHookContexts, useStore } from '../src' @@ -699,4 +699,63 @@ describe('createFormHook', () => { const button = getByText('Testing') expect(button).toBeInTheDocument() }) + + it('should render FieldGroup Subscribe without selector (default identity)', async () => { + const formOpts = formOptions({ + defaultValues: { + person: { + firstName: 'FirstName', + lastName: 'LastName', + }, + }, + }) + + const ChildFormAsField = withFieldGroup({ + defaultValues: formOpts.defaultValues.person, + render: ({ group }) => { + return ( +
+ ( + + )} + /> + ( + + {state.values.lastName} + + )} + /> +
+ ) + }, + }) + + const Parent = () => { + const form = useAppForm({ + ...formOpts, + }) + return + } + + const { getByTestId } = render() + const input = getByTestId('lastName') + const stateLastName = getByTestId('state-lastName') + + expect(stateLastName).toHaveTextContent('LastName') + + await user.clear(input) + await user.type(input, 'Updated') + await waitFor(() => expect(stateLastName).toHaveTextContent('Updated')) + }) }) diff --git a/packages/react-form/tests/useForm.test.tsx b/packages/react-form/tests/useForm.test.tsx index ce6733fcb..f93c07308 100644 --- a/packages/react-form/tests/useForm.test.tsx +++ b/packages/react-form/tests/useForm.test.tsx @@ -1075,4 +1075,45 @@ describe('useForm', () => { await user.click(getByText('Rerender')) await findByText('Another') }) + + it('should render Subscribe without selector (default identity)', async () => { + function Comp() { + const form = useForm({ + defaultValues: { + name: 'test', + }, + }) + + return ( + <> + ( + field.handleChange(e.target.value)} + /> + )} + /> + + ( + {state.values.name} + )} + /> + + ) + } + + const { getByTestId } = render() + const input = getByTestId('input') + const stateValue = getByTestId('state-value') + + expect(stateValue).toHaveTextContent('test') + + await user.clear(input) + await user.type(input, 'updated') + await waitFor(() => expect(stateValue).toHaveTextContent('updated')) + }) })