Skip to content

Commit b994a2a

Browse files
fix(form-core): fix form.resetField() ignoring nested fields (#1497)
Co-authored-by: Harry Whorlow <[email protected]>
1 parent 2a82baa commit b994a2a

File tree

3 files changed

+118
-6
lines changed

3 files changed

+118
-6
lines changed

packages/form-core/src/FormApi.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2136,12 +2136,9 @@ export class FormApi<
21362136
...prev.fieldMetaBase,
21372137
[field]: defaultFieldMeta,
21382138
},
2139-
values: {
2140-
...prev.values,
2141-
[field]:
2142-
this.options.defaultValues &&
2143-
this.options.defaultValues[field as keyof TFormData],
2144-
},
2139+
values: this.options.defaultValues
2140+
? setBy(prev.values, field, getBy(this.options.defaultValues, field))
2141+
: prev.values,
21452142
}
21462143
})
21472144
}

packages/form-core/tests/FormApi.spec.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3639,3 +3639,88 @@ it('should mark sourceMap as undefined when async field error is resolved', asyn
36393639

36403640
expect(field.getMeta().errorSourceMap.onChange).toBeUndefined()
36413641
})
3642+
3643+
it('should reset nested object fields', () => {
3644+
const defaultValues = {
3645+
shallow: '',
3646+
nested: {
3647+
field: {
3648+
name: '',
3649+
},
3650+
},
3651+
}
3652+
3653+
const form = new FormApi({
3654+
defaultValues,
3655+
})
3656+
form.mount()
3657+
3658+
form.setFieldValue('shallow', 'Shallow')
3659+
form.setFieldValue('nested.field.name', 'Nested')
3660+
3661+
expect(form.state.values.shallow).toEqual('Shallow')
3662+
expect(form.state.values.nested.field.name).toEqual('Nested')
3663+
3664+
form.resetField('shallow')
3665+
expect(form.state.values.shallow).toEqual('')
3666+
3667+
form.resetField('nested.field.name')
3668+
expect(form.state.values.nested.field.name).toEqual('')
3669+
})
3670+
3671+
it('should reset nested array fields', () => {
3672+
const defaultValues = {
3673+
shallow: '',
3674+
nested: {
3675+
arr: [{ name: '' }, { test: 'array-test' }],
3676+
},
3677+
}
3678+
3679+
const form = new FormApi({
3680+
defaultValues,
3681+
})
3682+
form.mount()
3683+
3684+
form.setFieldValue('shallow', 'Shallow')
3685+
form.setFieldValue('nested.arr[0].name', 'nested-arr')
3686+
form.setFieldValue('nested.arr[1].test', 'array-test-changed')
3687+
3688+
expect(form.state.values.shallow).toEqual('Shallow')
3689+
expect(form.state.values.nested.arr[0]?.name).toEqual('nested-arr')
3690+
expect(form.state.values.nested.arr[1]?.test).toEqual('array-test-changed')
3691+
3692+
form.resetField('shallow')
3693+
expect(form.state.values.shallow).toEqual('')
3694+
3695+
form.resetField('nested.arr[0].name')
3696+
expect(form.state.values.nested.arr[0]?.name).toEqual('')
3697+
expect(form.state.values.nested.arr[1]?.test).toEqual('array-test-changed')
3698+
})
3699+
3700+
it('should preserve nested fields on resetField if defaultValues is not provided', () => {
3701+
const state = {
3702+
shallow: '',
3703+
nested: {
3704+
field: {
3705+
name: '',
3706+
},
3707+
},
3708+
}
3709+
3710+
const form = new FormApi({
3711+
defaultState: { values: state },
3712+
})
3713+
form.mount()
3714+
3715+
form.setFieldValue('shallow', 'Shallow')
3716+
form.setFieldValue('nested.field.name', 'Nested')
3717+
3718+
expect(form.state.values.shallow).toEqual('Shallow')
3719+
expect(form.state.values.nested.field.name).toEqual('Nested')
3720+
3721+
form.resetField('shallow')
3722+
expect(form.state.values.shallow).toEqual('Shallow')
3723+
3724+
form.resetField('nested.field.name')
3725+
expect(form.state.values.nested.field.name).toEqual('Nested')
3726+
})

packages/form-core/tests/FormApi.test-d.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,33 @@ it('should only allow array fields for array-specific methods', () => {
273273
// @ts-expect-error too wide!
274274
const validate3 = form.validateArrayFieldsStartingFrom<RandomKeys>
275275
})
276+
277+
it('should infer full field name union for form.resetField parameters', () => {
278+
type FormData = {
279+
shallow: string
280+
nested: {
281+
field: {
282+
name: string
283+
}
284+
}
285+
}
286+
287+
const defaultValue = {
288+
shallow: '',
289+
nested: {
290+
field: {
291+
name: '',
292+
},
293+
},
294+
}
295+
296+
const form = new FormApi({
297+
defaultValues: defaultValue as FormData,
298+
})
299+
300+
expectTypeOf(form.resetField)
301+
.parameter(0)
302+
.toEqualTypeOf<
303+
'shallow' | 'nested' | 'nested.field' | 'nested.field.name'
304+
>()
305+
})

0 commit comments

Comments
 (0)