Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/form-core/src/FieldApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,10 @@ export class FieldApi<
mount = () => {
const cleanup = this.store.mount()

if ((this.options.defaultValue as unknown) !== undefined) {
if (
(this.options.defaultValue as unknown) !== undefined &&
!this.form.isFieldDeleted(this.name)
) {
this.form.setFieldValue(this.name, this.options.defaultValue as never, {
dontUpdateMeta: true,
})
Expand Down
40 changes: 40 additions & 0 deletions packages/form-core/src/FormApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,12 @@ export class FormApi<
* @private
*/
private _devtoolsSubmissionOverride: boolean
/**
* @private
* Tracks fields that have been explicitly deleted via deleteField()
* to prevent them from being restored by field mount() with defaultValue
*/
private _deletedFields: Set<string> = new Set()

/**
* Constructs a new `FormApi` instance with the given form options.
Expand Down Expand Up @@ -1468,6 +1474,8 @@ export class FormApi<
const { fieldMeta: currentFieldMeta } = this.state
const fieldMetaBase = this.resetFieldMeta(currentFieldMeta)

this._deletedFields.clear()

if (values && !opts?.keepDefaultValues) {
this.options = {
...this.options,
Expand Down Expand Up @@ -1642,6 +1650,11 @@ export class FormApi<
for (const field of Object.keys(
this.state.fieldMeta,
) as DeepKeys<TFormData>[]) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (this.baseStore.state.fieldMetaBase[field] === undefined) {
continue
}

const fieldMeta = this.getFieldMeta(field)
if (!fieldMeta) continue

Expand Down Expand Up @@ -1845,6 +1858,11 @@ export class FormApi<
for (const field of Object.keys(
this.state.fieldMeta,
) as DeepKeys<TFormData>[]) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (this.baseStore.state.fieldMetaBase[field] === undefined) {
continue
}

const fieldMeta = this.getFieldMeta(field)
if (!fieldMeta) continue

Expand Down Expand Up @@ -2219,6 +2237,14 @@ export class FormApi<
const dontRunListeners = opts?.dontRunListeners ?? false
const dontValidate = opts?.dontValidate ?? false

if (this._deletedFields.has(field as string)) {
return
}

if (!opts?.dontUpdateMeta) {
this._deletedFields.delete(field as string)
}

batch(() => {
if (!dontUpdateMeta) {
this.setFieldMeta(field, (prev) => ({
Expand Down Expand Up @@ -2250,6 +2276,14 @@ export class FormApi<
}
}

/**
* Checks if a field has been explicitly deleted and should not be restored
* @private
*/
isFieldDeleted = <TField extends DeepKeys<TFormData>>(field: TField) => {
return this._deletedFields.has(field as string)
}

deleteField = <TField extends DeepKeys<TFormData>>(field: TField) => {
const subFieldsToDelete = Object.keys(this.fieldInfo).filter((f) => {
const fieldStr = field.toString()
Expand All @@ -2258,6 +2292,10 @@ export class FormApi<

const fieldsToDelete = [...subFieldsToDelete, field]

fieldsToDelete.forEach((f) => {
this._deletedFields.add(f)
})

// Cleanup the last fields
this.baseStore.setState((prev) => {
const newState = { ...prev }
Expand Down Expand Up @@ -2472,6 +2510,8 @@ export class FormApi<
* Resets the field value and meta to default state
*/
resetField = <TField extends DeepKeys<TFormData>>(field: TField) => {
this._deletedFields.delete(field as string)

this.baseStore.setState((prev) => {
return {
...prev,
Expand Down
Loading