Skip to content

Commit

Permalink
fix(core): unmounted field skip validation (#2066)
Browse files Browse the repository at this point in the history
  • Loading branch information
j-xzy authored Aug 30, 2021
1 parent 0d9c20d commit 5739fda
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
17 changes: 17 additions & 0 deletions packages/core/src/__tests__/field.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,23 @@ test('deep nested fields hidden and validate with middle hidden', async () => {
expect(form.invalid).toBeFalsy()
})

test('fields unmount and validate', async () => {
const form = attach(createForm())
const field = attach(
form.createField({
name: 'parent',
required: true,
})
)
try {
await form.validate()
} catch {}
expect(form.invalid).toBeTruthy()
field.onUnmount();
await form.validate()
expect(form.invalid).toBeFalsy()
})

test('auto clean with ArrayField', () => {
const form = attach(createForm())
attach(
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/shared/internals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ export const validateToFeedbacks = async (
const takeSkipCondition = () => {
if (field.display !== 'visible') return true
if (field.pattern !== 'editable') return true
if (field.unmounted) return true
return false
}

Expand Down
52 changes: 51 additions & 1 deletion packages/react/src/__tests__/field.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { act } from 'react-dom/test-utils'
import { render, fireEvent, waitFor } from '@testing-library/react'
import { createForm } from '@formily/core'
import { createForm, onFieldUnmount } from '@formily/core'
import {
isField,
Field as FieldType,
Expand Down Expand Up @@ -235,3 +235,53 @@ test('connect', async () => {
expect(queryByText('read pretty')).toBeVisible()
})
})

test('fields unmount and validate', async () => {
const fn = jest.fn();
const form = createForm({
initialValues: {
parent: {
type: 'mounted',
}
},
effects: () => {
onFieldUnmount('parent.child', () => {
fn()
})
}
})
const Parent = observer(() => {
const field = useField()
if (field.value.type === 'mounted') {
return <Field name='child' component={[Input]} validator={{required: true}} />
}
return <div data-testid='unmounted'></div>
})
act(async () => {
const MyComponent = () => {
return (
<FormProvider form={form}>
<Field name='parent' component={[Parent]} />
</FormProvider>
)
}
render(<MyComponent />)
try {
await form.validate()
} catch {}

expect(form.invalid).toBeTruthy()

form.query('parent').take((field) => {
field.setState((state) => {
state.value.type = 'unmounted'
})
})

await waitFor(() => {
expect(fn.mock.calls.length).toBe(1)
});
await form.validate()
expect(form.invalid).toBeFalsy()
})
})

0 comments on commit 5739fda

Please sign in to comment.