Skip to content

Commit

Permalink
fix(core): fix field reactions still trigger when destroyed (#3103)
Browse files Browse the repository at this point in the history
* fix(core): fix field reactions still trigger when destroyed

* fix(core): fix field reactions still trigger when destroyed
  • Loading branch information
janryWang committed May 9, 2022
1 parent 679efc5 commit 23b06db
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 17 deletions.
44 changes: 28 additions & 16 deletions packages/core/src/__tests__/field.spec.ts
@@ -1,4 +1,4 @@
import { autorun, batch } from '@formily/reactive'
import { autorun, batch, observable } from '@formily/reactive'
import { createForm, onFieldReact, isField } from '../'
import { DataField } from '../types'
import { attach, sleep } from './shared'
Expand Down Expand Up @@ -2109,29 +2109,25 @@ test('destroy field need auto remove initialValues', () => {
})

test('validateFirst', async () => {
const form = attach(createForm<any>({
validateFirst: false
}))
const form = attach(
createForm<any>({
validateFirst: false,
})
)
const aaValidate = jest.fn(() => 'aaError')
const aa = attach(
form.createField({
name: 'aa',
validateFirst: true,
validator: [
aaValidate,
aaValidate,
]
validator: [aaValidate, aaValidate],
})
)
await aa.onInput('aa')
const bbValidate = jest.fn(() => 'bbError')
const bb = attach(
form.createField({
name: 'bb',
validator: [
bbValidate,
bbValidate,
],
validator: [bbValidate, bbValidate],
validateFirst: false,
})
)
Expand All @@ -2140,10 +2136,7 @@ test('validateFirst', async () => {
const cc = attach(
form.createField({
name: 'cc',
validator: [
ccValidate,
ccValidate,
],
validator: [ccValidate, ccValidate],
})
)
await cc.onInput('cc')
Expand All @@ -2152,3 +2145,22 @@ test('validateFirst', async () => {
expect(bbValidate).toBeCalledTimes(2)
expect(ccValidate).toBeCalledTimes(2)
})

test('reactions should not be triggered when field destroyed', () => {
const form = attach(createForm<any>())
const handler = jest.fn()
const obs = observable({ bb: 123 })
const aa = attach(
form.createField({
name: 'aa',
initialValue: 'test',
reactions() {
handler(obs.bb)
},
})
)
obs.bb = 321
aa.destroy()
obs.bb = 111
expect(handler).toBeCalledTimes(2)
})
4 changes: 4 additions & 0 deletions packages/core/src/models/BaseField.ts
Expand Up @@ -124,6 +124,10 @@ export class BaseField<Decorator = any, Component = any, TextType = any> {
return this.display === 'visible'
}

get destroyed() {
return !this.form.fields[this.address.toString()]
}

set hidden(hidden: boolean) {
if (!isValid(hidden)) return
if (hidden) {
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/shared/internals.ts
Expand Up @@ -1063,7 +1063,14 @@ export const createReactions = (field: GeneralField) => {
field.form.addEffects(field, () => {
reactions.forEach((reaction) => {
if (isFn(reaction)) {
field.disposers.push(autorun(batch.scope.bound(() => reaction(field))))
field.disposers.push(
autorun(
batch.scope.bound(() => {
if (field.destroyed) return
reaction(field)
})
)
)
}
})
})
Expand Down

0 comments on commit 23b06db

Please sign in to comment.