在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}
/>
);
}
}