Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] 列动态设置时,多个ListColumn设置CustomLayout会导致销毁异常,直接白屏 #3142

Open
linlinjiang opened this issue Dec 18, 2024 · 3 comments
Assignees
Labels
bug Something isn't working

Comments

@linlinjiang
Copy link

Version

1.13.2

Link to Minimal Reproduction

https://visactor.io/vtable/demo-react/custom-layout/cell-custom-dom

Steps to Reproduce

import * as ReactVTable from "@visactor/react-vtable";
const { ListTable, ListColumn, Group, Text, Image } = ReactVTable;
<ListTable {...option} records={tableData?.data} ref={tableRef} ReactDOM={ReactDom}>
        {columnState}
 </ListTable>

columnState是根据数据setState更新,格式如下

 <ListColumn key={dynamicFieldKey} {...commonProps} >
      <CustomComponent 
        role="custom-layout"
        element={xxxxx}
      />
 </ListColumn>
  const CustomComponent = useCallback((props: any) => {
    const { table, row, col, rect, value, element } = props;
    const rowData = table.getRecordByCell(col, row);
    const { height, width } = rect || table.getCellRect(col, row);
    return (
      <Group
        attribute={{
          width,
          height,
          react: {
            height,
            width,
            pointerEvents: true,
            container: table.bodyDomContainer, // table.headerDomContainer
            element: (
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  height: "100%",
                  paddingLeft: 9,
                  userSelect: "none",
                }}
              >
                {element?.(value, rowData)}
              </div>
            ),
          },
        }}
      />
    );
  }, []);

Current Behavior

手动新增或删除列展示后直接白屏
控制台报错
image
image
image

Expected Behavior

能正常展示

Environment

- OS:window
- Browser:谷歌
- Framework:react@18.2.0

Any additional comments?

No response

@linlinjiang linlinjiang added the bug Something isn't working label Dec 18, 2024
@Rui-Sun
Copy link
Contributor

Rui-Sun commented Dec 19, 2024

可以提供一下复现环境吗?我这么配置没能复现问题
image

@linlinjiang
Copy link
Author

import * as ReactVTable from "@visactor/react-vtable";
import { useCallback, useEffect, useState } from "react";
const { ListTable, ListColumn, Group } = ReactVTable;
import * as VTable from "@visactor/vtable";
import type { ListTableProps } from "@visactor/react-vtable/es/tables/list-table";
import { Button } from "@arco-design/web-react";
import ReactDom from "react-dom/client";

import cs from "./cs.jpeg";

const option: ListTableProps = {
  limitMaxAutoWidth: 200,
  autoFillWidth: true,
  theme: VTable.themes.ARCO,
  frozenColCount: 2,
  select: {
    disableSelect: true,
  },
  dragHeaderMode: "column",
  frozenColDragHeaderMode: "disabled",
  tooltip: {
    isShowOverflowTextTooltip: true,
  },
};

function generateRandomString(length) {
  let result = "";
  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * characters.length));
  }
  return result;
}

function App() {
  const [columnData, setColumnData] = useState([
    {
      display: true,
      field: "name",
      title: "title",
    },
    {
      display: true,
      field: "state",
      title: "state",
    },
    {
      display: true,
      field: "id",
      title: "id",
    }
  ]);
  const [columns, setColumns] = useState<any[]>([]);

  const CustomComponent = useCallback((props: any) => {
    const { table, row, col, rect, value, element } = props;
    const rowData = table.getRecordByCell(col, row);
    const { height, width } = rect || table.getCellRect(col, row);
    return (
      <Group
        attribute={{
          width,
          height,
          react: {
            height,
            width,
            pointerEvents: true,
            container: table.bodyDomContainer, // table.headerDomContainer
            element: (
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  height: "100%",
                  paddingLeft: 9,
                  userSelect: "none",
                }}
              >
                {element?.(value, rowData)}
              </div>
            ),
          },
        }}
      />
    );
  }, []);

  const renderSalaryStatus = useCallback((_: number, record: any) => {
    return <div>123</div>
  }, []);

  useEffect(() => {
    const list = columnData
      .filter((item) => item.display)
      .map((item) => {
        const { field, title } = item;
        const commonProps = {
          field: field,
          value: field,
          title: title,
          width: "auto",
        };

        switch (field) {
          case "name": {
            const newProps = {
              ...commonProps,
              icon: {
                type: "image",
                src: "icon",
                name: "Avatar",
                shape: "circle",
                width: 20,
                height: 20,
                positionType: VTable.TYPES.IconPosition.contentLeft,
                marginRight: 6,
                marginLeft: 0,
              },
              customRender: (args) => {
                const { table, row, col } = args;
                const rowData = table.getRecordByCell(col, row);
                const { employeeStatus } = rowData;
                const elements = [] as any[];
                let expectedWidth = 100;
                if ([2, 4].includes(employeeStatus)) {
                  expectedWidth += 30;
                  elements.push({
                    type: "rect",
                    fill: "#fafafa",
                    x: 85,
                    y: 12,
                    width: 40,
                    height: 15,
                  });
                  elements.push({
                    type: "text",
                    fill: "#959595",
                    fontSize: 10,
                    textBaseline: "top",
                    text: 4444,
                    x: 90,
                    y: 15,
                  });
                }

                return {
                  elements: elements,
                  expectedWidth: expectedWidth,
                  renderDefault: true,
                };
              },
            } as any;
            return <ListColumn key={field} {...newProps} />;
          }
          case "state": {
            return (
              <ListColumn key={field} {...commonProps} width={110}>
                <CustomComponent
                  role="custom-layout"
                  element={renderSalaryStatus}
                />
              </ListColumn>
            );
          }
          default: {
            return <ListColumn key={field} {...commonProps} />;
          }
        }
      });

    setColumns(list);
  }, [columnData, CustomComponent, renderSalaryStatus]);

  const records = [] as any[];
  for (let i = 0; i < 50; i++) {
    records.push({
      id: i,
      name: generateRandomString(8),
      state: i % 2 === 0 ? 1 : 2,
      employeeStatus: i % 2 === 0 ? 2 : 4,
      icon: cs,
    });
  }

  return (
    <div>
      <Button
        onClick={() =>
          setColumnData((prev) => {
            let newArr = [...prev];
            newArr[0].display = !newArr[0].display;
            return newArr;
          })
        }
      >
        按钮
      </Button>
      <ListTable
        {...option}
        records={records}
        height={900}
        defaultRowHeight={110}
        ReactDOM={ReactDom}
      >
        {columns}
      </ListTable>
    </div>
  );
}

export default App;

image
点击按钮
image

@linlinjiang
Copy link
Author

还是上面的那个例子,升级到1.14.0后出现了新的报错
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants