Skip to content

antd TreeSelect获取父节点的值

Published: at 01:05 PM

在antd对Treeselect组件的渲染中,onChange事件是无法获取父元素的值的,官方解释是处于对性能的考虑,没有对父元素进行关联。

文档末尾也给出了如何获取父元素值的方法,解题思路是:根据treeData的数据结构利用递归回溯去查找父节点的值

忠于文档~

import React from "react";
import { TreeSelect } from "antd";
import { Post } from "../../api/index";

const valueMap = {};
function loops(list, parent) {
  return (list || []).map(({ children, value }) => {
    const node = (valueMap[value] = {
      parent,
      value,
    });
    node.children = loops(children, node);
    return node;
  });
}
// 查找父节点的值
function getPath(value) {
  const path = [];
  let current = valueMap[value];
  while (current) {
    path.unshift(current.value);
    current = current.parent;
  }
  return path;
}

/**
 * 格式化树形机构
 */
function formatTree(
  list = [],
  formatFun,
  childrenName = "children",
  index = 0,
  dep = -1
) {
  return list.map((z, i) => {
    const hasChildren = !!(z[childrenName] || []).length;
    let c = null;
    if (dep === -1 || index < dep) {
      c = hasChildren
        ? formatTree(
            z[childrenName] || [],
            formatFun,
            childrenName,
            index + 1,
            dep
          )
        : null;
      console.log(111, z.name, index < dep, c);
    }
    //c = hasChildren ? formatTree(z[childrenName] || [], formatFun, childrenName, index + 1) : null;
    return {
      ...formatFun(z, i),
      hasChildren,
      level: index,
      children: c,
    };
  });
}

class Test extends React.PureComponent {
  state = {
    districts: "北京",
    districtsList: [],
  };

  componentDidMount() {
    Post("district/treeList").then(res => {
      const districts = res.data[0].name;
      getData.setDistricts(districts); // 保存为全局
      this.setState(
        {
          districtsList: formatTree(
            res.data,
            function (z) {
              return {
                title: z.name,
                value: z.name,
              };
            },
            "childList",
            0,
            1
          ),
          districts: districts,
        },
        () => {
          // 这是我自己其他的业务逻辑 可忽略
          this.update();
          const updateTime = process.env.REACT_APP_SITE_REFRESH_TIME;
          this.timer = setInterval(() => {
            this.update();
          }, +updateTime * 1000);
          // 这才是重点
          loops(this.state.districtsList);
        }
      );
    });
  }

  onChangeArea = value => {
    console.log(getPath(value));
    const new_district = getPath(value).join("-");
    getData.setDistricts(new_district);
    this.setState({
      districts: value,
    });
  };

  render() {
    const { districts, districtsList } = this.state;
    return (
      <TreeSelect
        showSearch
        dropdownMatchSelectWidth={300}
        size="small"
        value={districts}
        treeData={districtsList}
        placeholder="请选择区域"
        treeDefaultExpandAll
        onChange={this.onChangeArea}
      />
    );
  }
}