react使用antd-ProTable配置columns遇到的坑

535 阅读2分钟

1 需求

在了一个表格,过滤搜索需要做一个三级联动

image.png

2 代码实现

简单看一下代码部分的配置: 主要是做了三个Select框然后change的时候set数据

const [domainData, setDomainData] = useState<
  { value: string; label: string; sourceData: Level }[]
>([]);
const [subdomainData, setSubdomainData] = useState<
  { value: string; label: string; sourceData: Level }[]
>([]);
const [capabilityData, setCapabilityDataData] = useState<
  { value: string; label: string; sourceData: Level }[]
>([]);
const [level3Search, setLevel3Search] = useState({
  domainName: '',
  subdomainName: '',
  capabilityName: '',
});

useEffect(() => {
  getServiceCatalogLevel3().then((res) => {
    setDomainData(
      res.map((item) => ({
        value: item.key,
        label: item.title,
        sourceData: item,
      })),
    );
  });
}, []);

const columns =[
{
  title: intl.formatMessage({
    id: 'app.pwa.pages.domainName',
    defaultMessage: '领域',
  }),
  dataIndex: 'domainName',
  valueType: 'select',
  fieldProps: {
    options: domainData,
    showSearch: true,
    // value: level3Search.domainName,
    onChange: (
      value: string,
      options: {
        sourceData: Level;
      },
    ) => {
      if (value) {
        setLevel3Search({
          domainName: options.sourceData.title,
          subdomainName: '',
          capabilityName: '',
        });
        setSubdomainData(
          options.sourceData.children
            ? options.sourceData.children.map((item: Level) => ({
                value: item.key,
                label: item.title,
                sourceData: item,
              }))
            : [],
        );
      } else {
        setLevel3Search({
          domainName: '',
          subdomainName: '',
          capabilityName: '',
        });
        setSubdomainData([]);
      }
    },
  },
  search: {
    transform: () => level3Search.domainName,
  },
},
{
  title: '所属子领域',
  dataIndex: 'subdomainName',
  valueType: 'select',
  fieldProps: {
    options: subdomainData,
    showSearch: true,
    value: level3Search.subdomainName,
    disabled: !level3Search.domainName,
    onChange: (
      value: string,
      options: {
        sourceData: Level;
      },
    ) => {
      if (value) {
        setLevel3Search({
          ...level3Search,
          subdomainName: options.sourceData.title,
          capabilityName: '',
        });
        setCapabilityDataData(
          options.sourceData.children
            ? options.sourceData.children.map((item: Level) => ({
                value: item.key,
                label: item.title,
                sourceData: item,
              }))
            : [],
        );
      } else {
        setLevel3Search({
          ...level3Search,
          subdomainName: '',
          capabilityName: '',
        });
        setCapabilityDataData([]);
      }
    },
  },
  search: {
    transform: () => level3Search.subdomainName,
  },
},
{
  title: '所属能力',
  dataIndex: 'capabilityName',
  valueType: 'select',
  fieldProps: {
    options: capabilityData,
    showSearch: true,
    value: level3Search.capabilityName,
    disabled: !level3Search.subdomainName,
    onChange: (
      value: string,
      options: {
        sourceData: Level;
      },
    ) => {
      if (value) {
        setLevel3Search({
          ...level3Search,
          capabilityName: options.sourceData.title,
        });
      } else {
        setLevel3Search({
          ...level3Search,
          capabilityName: '',
        });
      }
    },
  },
  search: {
    transform: () => level3Search.capabilityName,
  },
},
]

3 遇到的问题

后端如果没有数据是没有返回字段的(也就是连key都没有)

吐槽一下:其实这个很蛋疼,当写ts的时候定义interface理论上来说不就都是?:

这个时候也就是展示为 "-" image.png 但是当我选择三个选项的时候,为空的会跟着变化 image.png

4 解决方案

随后就去翻了pro-components的源码,结果啥都没找到

  • 想要看看table的render默认是什么没找
  • 想找找valueType的相关代码也没看出啥

首先要先排除不是自己代码产生的问题最好的方式就是拉最基础的ant-design-pro

image.png

上图是根据ant-design-pro 搭的最初是的项目,根据排查得出结论

  • 和联动没有关系
  • 设计的肯定有问题,从第三点的截图看出如果有值的情况下是不会跟着变的,所以配置直观逻辑是没有问题的

直接看解决方式吧

4.1 方法一

删除fieldProps的value设置+配置search指向要过滤的数据

推测:应该是在我没找到的源码中,table列的render跟select有关联,默认render的时候需要关联Select数据

伪代码:

typeof render === 'function' ? render: defaultRender[valueType]

selectRender = ()=>{
 return valueEnum ? 处理valueEnmu的返回 
         : fieldProps?.[options]?.[value]
}

以上为推测想法,暂时没有找到源码,等有时间找的时候再看看

4.2 方法二

render:(_,rowData)=>rowData.你的key??'-'