alibaba / formily

📱🚀 🧩 Cross Device & High Performance Normal Form/Dynamic(JSON Schema) Form/Form Builder -- Support React/React Native/Vue 2/Vue 3
https://formilyjs.org/
MIT License
10.93k stars 1.42k forks source link

[Bug Report] ArrayField根据条件渲染不同的子组件(A、B),添加B,删除B,再添加A,报错,Cannot read properties of undefined (reading 'onMount') #4149

Open zrj1031 opened 1 month ago

zrj1031 commented 1 month ago

Reproduction link

Edit on CodeSandbox

Steps to reproduce

  1. 点击添加规则 2.点击添加规则组
  2. 删除第2步的规则组 4.添加规则 fINausvaIW

What is expected?

正常展示

What is actually happening?

报错白屏

Package

@formily/react@2.2.20


zrj1031 commented 1 month ago
import React from "react";
import { createForm, ArrayField as ArrayFieldType } from "@formily/core";
import {
  FormProvider,
  Field,
  ArrayField,
  useField,
  observer,
  ObjectField,
} from "@formily/react";
import { Input, Button, Space } from "antd";
import { nanoid } from "nanoid";

const form = createForm();

const BaseRule = (props: any) => {
  const { onRemove } = props;
  const field = useField();
  return (
    <>
      <span style={{ color: "red" }}>规则</span>
      {/* <Field name="deps" component={[() => "deps"]} /> */}
      <Button onClick={() => onRemove(field.index)}>删除</Button>
    </>
  );
};

const ArrayComponent = observer(() => {
  const field = useField<ArrayFieldType>();
  return (
    <div>
      {field.value?.map((item, index) => (
        <div key={item.id}>
          {item.logic ? (
            <ObjectField
              name={index}
              component={[
                () => (
                  <div style={{ display: "flex", marginBottom: 16 }}>
                    <span style={{ color: "green", marginRight: "12px" }}>
                      规则组
                    </span>

                    {/* <Field name="logic" component={[() => "logic"]} /> */}
                    <ArrayField name="strategy" component={[ArrayComponent]} />
                  </div>
                ),
              ]}
              reactions={[
                (selfField) => {
                  const empty = !selfField.value?.strategy?.length;
                  // selfField.setDisplay(empty ? 'none' : 'visible');
                  empty && field.remove(selfField.index as any);
                },
              ]}
            />
          ) : (
            <div style={{ display: "flex", gap: "12px" }}>
              <ObjectField
                name={index}
                component={[
                  BaseRule,
                  {
                    onRemove: field.remove,
                  },
                ]}
              />
            </div>
          )}
        </div>
      ))}
      <div style={{ display: "flex", gap: "12px" }}>
        <Button
          onClick={() =>
            field.push({
              id: nanoid(),
            })
          }
        >
          添加规则
        </Button>
        <Button
          onClick={() =>
            field.push({
              logic: "and",
              strategy: [
                {
                  id: nanoid(),
                },
              ],
            })
          }
        >
          添加规则组
        </Button>
      </div>
    </div>
  );
});

export default () => (
  <FormProvider form={form}>
    <ArrayField name="array" component={[ArrayComponent]} />
  </FormProvider>
);

附上代码