Просмотр исходного кода

fix(form): field array disposed (#588)

xiamidaxia 5 месяцев назад
Родитель
Сommit
753fbb2ed8

+ 4 - 0
packages/node-engine/form/src/core/field-model.ts

@@ -389,4 +389,8 @@ export class FieldModel<TValue extends FieldValue = FieldValue> implements Dispo
   onDispose(fn: () => void) {
     this.toDispose.onDispose(fn);
   }
+
+  get disposed() {
+    return this.toDispose.disposed;
+  }
 }

+ 10 - 6
packages/node-engine/form/src/react/field-array.tsx

@@ -45,12 +45,9 @@ export function FieldArray<TValue extends FieldValue>({
   children,
 }: FieldArrayProps<TValue>): React.ReactElement {
   const formModel = useFormModel();
-  const fieldModel = React.useMemo(
-    () =>
-      formModel.getField<FieldArrayModel<TValue>>(name) ||
-      (formModel.createFieldArray(name) as FieldArrayModel<any>),
-    [name]
-  );
+  const fieldModel =
+    formModel.getField<FieldArrayModel<TValue>>(name) ||
+    (formModel.createFieldArray(name) as FieldArrayModel<any>);
 
   const field = React.useMemo(() => toFieldArray<TValue>(fieldModel), [fieldModel]);
 
@@ -63,6 +60,11 @@ export function FieldArray<TValue extends FieldValue>({
   const formState = React.useMemo(() => toFormState(formModelState), [formModelState]);
 
   React.useEffect(() => {
+    // 当 FieldArray 加上 key 且 key 变化时候会销毁 FieldModel
+    if (fieldModel.disposed) {
+      refresh();
+      return () => {};
+    }
     fieldModel.renderCount = fieldModel.renderCount + 1;
 
     if (!formModel.getValueIn(name) !== undefined && defaultValue !== undefined) {
@@ -112,6 +114,8 @@ export function FieldArray<TValue extends FieldValue>({
     return <>Invalid Array render</>;
   };
 
+  if (fieldModel.disposed) return <></>;
+
   return (
     <FieldModelContext.Provider value={fieldModel}>{renderInner()}</FieldModelContext.Provider>
   );

+ 6 - 0
packages/node-engine/form/src/react/field.tsx

@@ -51,6 +51,11 @@ export function Field<TValue>({
   const refresh = useRefresh();
 
   React.useEffect(() => {
+    // 当 Field 加上 key 且 key 变化时候会销毁 FieldModel
+    if (fieldModel.disposed) {
+      refresh();
+      return () => {};
+    }
     fieldModel.renderCount = fieldModel.renderCount + 1;
 
     if (!formModel.getValueIn(name) !== undefined && defaultValue !== undefined) {
@@ -99,6 +104,7 @@ export function Field<TValue>({
 
     return React.cloneElement(children as React.ReactElement, { ...field });
   };
+  if (fieldModel.disposed) return <></>;
 
   return (
     <FieldModelContext.Provider value={fieldModel}>{renderInner()}</FieldModelContext.Provider>