Skip to content

Commit

Permalink
fix(core): fix ArrayField operation will trigger memo leak (#1831)
Browse files Browse the repository at this point in the history
  • Loading branch information
janryWang authored Jul 19, 2021
1 parent 6e541dc commit 021c155
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
36 changes: 36 additions & 0 deletions packages/core/src/__tests__/array.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createForm } from '../'
import { onFieldValueChange, onFormValuesChange } from '../effects'
import { attach } from './shared'

test('create array field', () => {
Expand Down Expand Up @@ -281,3 +282,38 @@ test('array field move api with children', async () => {
expect(form.fields['array.0.name']).not.toBeUndefined()
expect(form.fields['array.2.name']).toBeUndefined()
})

test('array field remove memo leak', async () => {
const handler = jest.fn()
const valuesChange = jest.fn()
const form = attach(
createForm({
effects() {
onFormValuesChange(valuesChange)
onFieldValueChange('*', handler)
},
})
)
const array = attach(
form.createArrayField({
name: 'array',
})
)
await array.push('')
attach(
form.createField({
name: '0',
basePath: 'array',
})
)
await array.remove(0)
await array.push('')
attach(
form.createField({
name: '0',
basePath: 'array',
})
)
expect(handler).toBeCalledTimes(1)
expect(valuesChange).toBeCalledTimes(4)
})
8 changes: 4 additions & 4 deletions packages/core/src/models/ArrayField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,35 +52,35 @@ export class ArrayField<
if (!isArr(this.value)) return
return batch(() => {
const index = this.value.length - 1
this.value.pop()
spliceArrayState(this, {
startIndex: index,
deleteCount: 1,
})
this.value.pop()
return this.onInput(this.value)
})
}

insert = async (index: number, ...items: any[]) => {
if (!isArr(this.value)) return
return batch(() => {
this.value.splice(index, 0, ...items)
spliceArrayState(this, {
startIndex: index,
insertCount: items.length,
})
this.value.splice(index, 0, ...items)
return this.onInput(this.value)
})
}

remove = async (index: number) => {
if (!isArr(this.value)) return
return batch(() => {
this.value.splice(index, 1)
spliceArrayState(this, {
startIndex: index,
deleteCount: 1,
})
this.value.splice(index, 1)
return this.onInput(this.value)
})
}
Expand All @@ -96,11 +96,11 @@ export class ArrayField<
unshift = async (...items: any[]) => {
if (!isArr(this.value)) return
return batch(() => {
this.value.unshift(...items)
spliceArrayState(this, {
startIndex: 0,
insertCount: items.length,
})
this.value.unshift(...items)
return this.onInput(this.value)
})
}
Expand Down
10 changes: 7 additions & 3 deletions packages/core/src/shared/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -662,16 +662,20 @@ export const triggerFormInitialValuesChange = (
form: Form,
change: DataChange
) => {
if (change.path[0] === 'initialValues') {
const path = change.path
if (path[path.length - 1] === 'length') return
if (path[0] === 'initialValues') {
if (change.type === 'add' || change.type === 'set') {
applyValuesPatch(form, change.path.slice(1), change.value)
applyValuesPatch(form, path.slice(1), change.value)
}
form.notify(LifeCycleTypes.ON_FORM_INITIAL_VALUES_CHANGE)
}
}

export const triggerFormValuesChange = (form: Form, change: DataChange) => {
if (change.path[0] === 'values') {
const path = change.path
if (path[path.length - 1] === 'length') return
if (path[0] === 'values') {
form.notify(LifeCycleTypes.ON_FORM_VALUES_CHANGE)
}
}

0 comments on commit 021c155

Please sign in to comment.