treeselect 异步获取子节点 - davy-gan/web GitHub Wiki

import React, { useState, useEffect } from react';
import { TreeSelect } from 'antd';

const { SHOW_PARENT } = TreeSelect;

function getNewTreeData(treeData, curKey, child) {
  const loop = data => {
    data.forEach(item => {
      if (curKey === item.key) {
        // eslint-disable-next-line no-param-reassign
        item.children = child;
      } else if (curKey.startsWith(`${item.key}$$`)) {
        if (item.children) {
          loop(item.children);
        }
      }
    });
  };
  loop(treeData);
  return treeData;
}

export default function DynamicTreeSelect({
  fetchTreeDataApi,
  maxLevel = 999,
  onChange,
  value,
  // defaultValue,
  ...props
}) {
  const [treeData, setTreeData] = useState([]);


  const wrapFetchTreeDataApi = async (params = {}) => {
    const { lastLevelValue = '', ...queryParams } = params;
    if (lastLevelValue) {
      queryParams.lastLevelValue = lastLevelValue.split('$$').pop();
    }
    let result = await fetchTreeDataApi(queryParams);
    if (result && result.success) {
      result = result.data;
      const isLeaf = queryParams.level === maxLevel;
      return result.map(t => {
        const value = `${lastLevelValue}$$${t.id}`;
        return {
          key: value,
          value,
          label: t.name,
          flag: t.flag,
          isLeaf,
        };
      });
    }
  };

  const loadData = async treeNode => {
    let newTreeData = [];
    if (!treeNode) {
      newTreeData = await wrapFetchTreeDataApi({ level: 1 });
    } else {
      const child = await wrapFetchTreeDataApi({
        level: treeNode.props.pos.split('-').length,
        lastLevelValue: treeNode.props.value,
      });
      newTreeData = getNewTreeData([...treeData], treeNode.props.eventKey, child);
    }
    setTreeData(newTreeData);
  };

  useEffect(() => {
    loadData();
  }, []);

  const wrapOnChange = (value, label, flag) => {
    console.log(value, 'value');
    const valueArr = [];
    valueArr.push(value);
    const realValue = valueArr.map(t => {
        const allValues = t.split('$$');
        const values = t.split('$$');
        return {
            level: values.length - 1,
            value: values.pop(),
            allValues,
        }
    })

    if (onChange) {
      onChange(realValue);
    }
  };

  const tProps = {
    treeData,
    loadData,
    onChange: wrapOnChange,
    showCheckedStrategy: SHOW_PARENT,
    size: 'large',
    // defaultValue,
    style: {
      width: 500,
    },
    ...props,
  };
  return <TreeSelect {...tProps} dropdownStyle={{ maxHeight: 400, overflow: 'auto' }} />;
}

<DynamicTreeSelect
  maxLevel={4}
  nChange={this.onChange}
  fetchTreeDataApi={listBizZoneFun}
/>,