File tree Expand file tree Collapse file tree 5 files changed +182
-3
lines changed Expand file tree Collapse file tree 5 files changed +182
-3
lines changed Original file line number Diff line number Diff line change @@ -370,3 +370,52 @@ describe('TanStackFieldDirective', () => {
370
370
expect ( getByText ( onBlurError ) ) . toBeInTheDocument ( )
371
371
} )
372
372
} )
373
+
374
+ describe ( 'form should reset default value when resetting in onSubmit' , ( ) => {
375
+ it ( 'should be able to handle async resets' , async ( ) => {
376
+ @Component ( {
377
+ selector : 'test-component' ,
378
+ standalone : true ,
379
+ template : `
380
+ <ng-container [tanstackField]="form" name="name" #f="field">
381
+ <input
382
+ data-testid="fieldinput"
383
+ [value]="f.api.state.value"
384
+ (input)="f.api.handleChange($any($event).target.value)"
385
+ />
386
+ </ng-container>
387
+ <button
388
+ type="button"
389
+ (click)="form.handleSubmit()"
390
+ data-testid="submit"
391
+ >
392
+ submit
393
+ </button>
394
+ ` ,
395
+ imports : [ TanStackField ] ,
396
+ } )
397
+ class TestComponent {
398
+ form = injectForm ( {
399
+ defaultValues : {
400
+ name : '' ,
401
+ } ,
402
+ onSubmit : ( { value } ) => {
403
+ expect ( value ) . toEqual ( { name : 'test' } )
404
+ this . form . reset ( { name : 'test' } )
405
+ } ,
406
+ } )
407
+ }
408
+
409
+ const { getByTestId } = await render ( TestComponent )
410
+
411
+ const input = getByTestId ( 'fieldinput' )
412
+ const submit = getByTestId ( 'submit' )
413
+
414
+ await user . type ( input , 'test' )
415
+ await expect ( input ) . toHaveValue ( 'test' )
416
+
417
+ await user . click ( submit )
418
+
419
+ await expect ( input ) . toHaveValue ( 'test' )
420
+ } )
421
+ } )
Original file line number Diff line number Diff line change @@ -120,6 +120,25 @@ describe('form api', () => {
120
120
} )
121
121
} )
122
122
123
+ it ( 'form should reset default value when resetting in onSubmit' , async ( ) => {
124
+ const defaultValues = {
125
+ name : '' ,
126
+ }
127
+ const form = new FormApi ( {
128
+ defaultValues : defaultValues ,
129
+ onSubmit : ( { value } ) => {
130
+ form . reset ( value )
131
+
132
+ expect ( form . options . defaultValues ) . toMatchObject ( {
133
+ name : 'test' ,
134
+ } )
135
+ } ,
136
+ } )
137
+ form . mount ( )
138
+ form . setFieldValue ( 'name' , 'test' )
139
+ form . handleSubmit ( )
140
+ } )
141
+
123
142
it ( 'should reset and set the new default values that are restored after an empty reset' , ( ) => {
124
143
const form = new FormApi ( { defaultValues : { name : 'initial' } } )
125
144
form . mount ( )
Original file line number Diff line number Diff line change 1
1
import { FormApi , functionalUpdate } from '@tanstack/form-core'
2
2
import { useStore } from '@tanstack/react-store'
3
- import React , { useState } from 'react'
3
+ import { useState } from 'react'
4
4
import { Field } from './useField'
5
5
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'
6
6
import type {
@@ -190,9 +190,11 @@ export function useForm<
190
190
TOnServer ,
191
191
TSubmitMeta
192
192
> = api as never
193
+
193
194
extendedApi . Field = function APIField ( props ) {
194
195
return < Field { ...props } form = { api } />
195
196
}
197
+
196
198
extendedApi . Subscribe = function Subscribe ( props : any ) {
197
199
return (
198
200
< LocalSubscribe
@@ -208,8 +210,6 @@ export function useForm<
208
210
209
211
useIsomorphicLayoutEffect ( formApi . mount , [ ] )
210
212
211
- useStore ( formApi . store , ( state ) => state . isSubmitting )
212
-
213
213
/**
214
214
* formApi.update should not have any side effects. Think of it like a `useRef`
215
215
* that we need to keep updated every render with the most up-to-date information.
Original file line number Diff line number Diff line change @@ -794,4 +794,64 @@ describe('useForm', () => {
794
794
795
795
expect ( fn ) . toHaveBeenCalledTimes ( 1 )
796
796
} )
797
+
798
+ it ( 'form should reset default value when resetting in onSubmit' , async ( ) => {
799
+ function Comp ( ) {
800
+ const form = useForm ( {
801
+ defaultValues : {
802
+ name : '' ,
803
+ } ,
804
+ onSubmit : ( { value } ) => {
805
+ expect ( value ) . toEqual ( { name : 'another-test' } )
806
+
807
+ form . reset ( value )
808
+ } ,
809
+ } )
810
+
811
+ return (
812
+ < form
813
+ onSubmit = { ( e ) => {
814
+ e . preventDefault ( )
815
+ e . stopPropagation ( )
816
+ form . handleSubmit ( )
817
+ } }
818
+ >
819
+ < form . Field
820
+ name = "name"
821
+ children = { ( field ) => (
822
+ < input
823
+ data-testid = "fieldinput"
824
+ name = { field . name }
825
+ value = { field . state . value }
826
+ onChange = { ( e ) => field . handleChange ( e . target . value ) }
827
+ />
828
+ ) }
829
+ />
830
+
831
+ < button type = "submit" data-testid = "submit" >
832
+ submit
833
+ </ button >
834
+
835
+ < button type = "reset" data-testid = "reset" onClick = { ( ) => form . reset ( ) } >
836
+ Reset
837
+ </ button >
838
+ </ form >
839
+ )
840
+ }
841
+
842
+ const { getByTestId } = render ( < Comp /> )
843
+ const input = getByTestId ( 'fieldinput' )
844
+ const submit = getByTestId ( 'submit' )
845
+ const reset = getByTestId ( 'reset' )
846
+
847
+ await user . type ( input , 'test' )
848
+ await waitFor ( ( ) => expect ( input ) . toHaveValue ( 'test' ) )
849
+
850
+ await user . click ( reset )
851
+ await waitFor ( ( ) => expect ( input ) . toHaveValue ( '' ) )
852
+
853
+ await user . type ( input , 'another-test' )
854
+ await user . click ( submit )
855
+ await waitFor ( ( ) => expect ( input ) . toHaveValue ( 'another-test' ) )
856
+ } )
797
857
} )
Original file line number Diff line number Diff line change @@ -476,4 +476,55 @@ describe('useForm', () => {
476
476
await waitFor ( ( ) => getByText ( error ) )
477
477
expect ( getByText ( error ) ) . toBeInTheDocument ( )
478
478
} )
479
+
480
+ it ( 'form should reset default value when resetting in onSubmit' , async ( ) => {
481
+ const Comp = defineComponent ( ( ) => {
482
+ const form = useForm ( {
483
+ defaultValues : {
484
+ name : '' ,
485
+ } ,
486
+ onSubmit : ( { value } ) => {
487
+ expect ( value ) . toEqual ( { name : 'test' } )
488
+
489
+ form . reset ( { name : 'test' } )
490
+ } ,
491
+ } )
492
+
493
+ return ( ) => (
494
+ < div >
495
+ < form . Field name = "name" >
496
+ { ( { field } : { field : AnyFieldApi } ) => (
497
+ < input
498
+ data-testid = "fieldinput"
499
+ name = { field . name }
500
+ value = { field . state . value }
501
+ onInput = { ( e ) =>
502
+ field . handleChange ( ( e . target as HTMLInputElement ) . value )
503
+ }
504
+ />
505
+ ) }
506
+ </ form . Field >
507
+
508
+ < button
509
+ type = "button"
510
+ onClick = { ( ) => form . handleSubmit ( ) }
511
+ data-testid = "submit"
512
+ >
513
+ submit
514
+ </ button >
515
+ </ div >
516
+ )
517
+ } )
518
+
519
+ const { getByTestId } = render ( < Comp /> )
520
+ const input = getByTestId ( 'fieldinput' )
521
+ const submit = getByTestId ( 'submit' )
522
+
523
+ await user . type ( input , 'test' )
524
+ await waitFor ( ( ) => expect ( input ) . toHaveValue ( 'test' ) )
525
+
526
+ await user . click ( submit )
527
+
528
+ await waitFor ( ( ) => expect ( input ) . toHaveValue ( 'test' ) )
529
+ } )
479
530
} )
You can’t perform that action at this time.
0 commit comments