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