From d705f56d92e7f4e744f820247373ca730be3a56e Mon Sep 17 00:00:00 2001 From: Janry Date: Sun, 12 Jun 2022 11:20:56 +0800 Subject: [PATCH] fix(react): fix field wrong mounted state (#3181) --- packages/react/src/__tests__/field.spec.tsx | 45 ++++++++++++++++++- .../src/__tests__/schema.markup.spec.tsx | 6 +-- packages/react/src/hooks/useAttach.ts | 11 +---- packages/react/src/types.ts | 2 +- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/packages/react/src/__tests__/field.spec.tsx b/packages/react/src/__tests__/field.spec.tsx index b7c0b7a43cd..6948387a0c6 100644 --- a/packages/react/src/__tests__/field.spec.tsx +++ b/packages/react/src/__tests__/field.spec.tsx @@ -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, onFieldUnmount } from '@formily/core' +import { createForm, onFieldUnmount, isArrayField } from '@formily/core' import { isField, Field as FieldType, @@ -33,7 +33,7 @@ type CustomProps = { list?: string[] } -const Decorator: React.FC = (props) =>
{props.children}
+const Decorator = (props) =>
{props.children}
const Input: React.FC> = (props) => ( { expect(form.query('bb').take().mounted).toBeTruthy() }) +test('useAttach with array field', async () => { + const form = createForm() + const MyComponent = () => { + return ( + + + {(field) => { + return field.value.map((val, index) => { + return ( + + ) + }) + }} + + + ) + } + render() + await waitFor(() => { + expect(form.query('array.0.input').take().mounted).toBeTruthy() + expect(form.query('array.1.input').take().mounted).toBeTruthy() + }) + form.query('array').take((field) => { + if (isArrayField(field)) { + field.moveDown(0) + } + }) + await waitFor(() => { + expect(form.query('array.0.input').take().mounted).toBeTruthy() + expect(form.query('array.1.input').take().mounted).toBeTruthy() + }) +}) + test('useFormEffects', async () => { const form = createForm() const CustomField = observer(() => { diff --git a/packages/react/src/__tests__/schema.markup.spec.tsx b/packages/react/src/__tests__/schema.markup.spec.tsx index abad3ea1185..a14865864e2 100644 --- a/packages/react/src/__tests__/schema.markup.spec.tsx +++ b/packages/react/src/__tests__/schema.markup.spec.tsx @@ -107,7 +107,7 @@ describe('markup schema field', () => { }) test('void', () => { const form = createForm() - const VoidComponent: React.FC = (props) => { + const VoidComponent = (props) => { return
{props.children}
} const SchemaField = createSchemaField({ @@ -178,7 +178,7 @@ describe('markup schema field', () => { }) test('props children', () => { const form = createForm() - const Text: React.FC = (props) => { + const Text = (props) => { return
{props.children}
} const SchemaField = createSchemaField({ @@ -201,7 +201,7 @@ describe('markup schema field', () => { }) test('x-content', () => { const form = createForm() - const Text: React.FC = (props) => { + const Text = (props) => { return
{props.children}
} const SchemaField = createSchemaField({ diff --git a/packages/react/src/hooks/useAttach.ts b/packages/react/src/hooks/useAttach.ts index aa19c58afe7..fae7ad9269c 100644 --- a/packages/react/src/hooks/useAttach.ts +++ b/packages/react/src/hooks/useAttach.ts @@ -1,4 +1,4 @@ -import { useRef, useEffect } from 'react' +import { useEffect } from 'react' interface IRecycleTarget { onMount: () => void @@ -6,16 +6,9 @@ interface IRecycleTarget { } export const useAttach = (target: T): T => { - const oldTargetRef = useRef(null) useEffect(() => { - if (oldTargetRef.current && target !== oldTargetRef.current) { - oldTargetRef.current.onUnmount() - } - oldTargetRef.current = target target.onMount() - return () => { - target.onUnmount() - } + return () => target.onUnmount() }, [target]) return target } diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts index a4808508526..4b537f2be4d 100644 --- a/packages/react/src/types.ts +++ b/packages/react/src/types.ts @@ -28,7 +28,7 @@ export interface IFormSpyProps { } export type RenderPropsChildren = - | ((field: Payload, form: Form) => ReactChild) + | ((field: Payload, form: Form) => React.ReactNode) | React.ReactNode export interface IFieldProps<