最近做前端项目时,使用到了
tree
组件,选择使用Ant Design
中的tree
组件,默认所有节点初始时全部展开,使用defaultExpandAll
属性。但是显示的时候,一个节点都没展开。于是调研了一下这个问题。发现有以下问题:
1、TreeData
数据 未初始化完成
,还未开始渲染,就已经开始展开。
一般treeData 数据获取都是从接口获取,是异步操作,会有段初始化时间,这时treeData未初始化完成,就开始展开,会出现问题。解决办法:
如果还会存在问题,没有正常展开,就是下面的问题了。
2、defaultExpandAll
属性无法生效,与其他属性 冲突
,没错,就和这个 expandedKeys
属性冲突。
解决方案:判断 treeData
是否初始化完成,使用 defaultExpandedKeys
代替 expandedKeys
属性。
<div>
// 修改1
{treeData.length > 0 &&
<Tree
checkable
onExpand={onExpand}
// expandedKeys={expandedKeys}
// 修改2
defaultExpandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={treeData}
defaultExpandAll={true}
/>
}
</div>
完整代码
这个代码里面加了点业务,就是说根据两个 互斥
的 button
按钮,点击按钮的时候,会根据不同的 typeVal
返回 不同的树结构
,如果都放在一个 treeData
中,第二次点击的时候,就会出现 数据为初始化,展开不生效
的问题,没想出特别好的办法,于是设置了 treeDataOne
和 treeDataTwo
,分别展示。这里大家如果有比较好的解决办法,希望可以评论一下,学习一下。
import { Tree } from 'antd';
import type { DataNode } from 'antd/es/tree';
import React, { useState, useEffect } from 'react';
const treeData: DataNode[] = [
{
title: '0-0',
key: '0-0',
children: [
{
title: '0-0-0',
key: '0-0-0',
children: [
{ title: '0-0-0-0', key: '0-0-0-0' },
{ title: '0-0-0-1', key: '0-0-0-1' },
{ title: '0-0-0-2', key: '0-0-0-2' },
],
},
{
title: '0-0-1',
key: '0-0-1',
children: [
{ title: '0-0-1-0', key: '0-0-1-0' },
{ title: '0-0-1-1', key: '0-0-1-1' },
{ title: '0-0-1-2', key: '0-0-1-2' },
],
},
{
title: '0-0-2',
key: '0-0-2',
},
],
},
{
title: '0-1',
key: '0-1',
children: [
{ title: '0-1-0-0', key: '0-1-0-0' },
{ title: '0-1-0-1', key: '0-1-0-1' },
{ title: '0-1-0-2', key: '0-1-0-2' },
],
},
{
title: '0-2',
key: '0-2',
},
];
const ButtonMenu = [{ key: 0, value: 'one' }, { key: 1, value: 'two' }];
const App: React.FC = () => {
const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
const [checkedKeys, setCheckedKeys] = useState<React.Key[]>([]);
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
const [treeDataTwo, setTreeDataOne] = useState<DataNode[]>([]);
const [treeDataTwo, setTreeDataTwo] = useState<DataNode[]>([]);
const [typeVal, setTypeVal] = useState<number>();
const onExpand = (expandedKeysValue: React.Key[]) => {
setExpandedKeys(expandedKeysValue);
setAutoExpandParent(false);
};
const onCheck = (checkedKeysValue: React.Key[]) => {
setCheckedKeys(checkedKeysValue);
};
const onSelect = (selectedKeysValue: React.Key[], info: any) => {
setSelectedKeys(selectedKeysValue);
};
const handleChangeType = (type: number) => {
setTypeVal(type);
}
// 本例上treeData是本地写死的,但是项目中一般会使用接口获取。
useEffect(() => {
getTreeData({ type : typeVal }).then(res) => {
// 这里加一点业务,根据type的类型不同,获取不同的treeData
if(typeVal === 0) setTreeDataOne(res.data[typeVal]);
else if (typeVal === 1) setTreeDataTwo(res.data[typeVal]);
}
})
return (<div>
<div>
{ButtonMenu.map((account: number) => (
<button key={account.key} onClick={() => handleChangeType(account.key)}>
{account.value}
</button>
))}
</div>
<div>
// 修改1
{typeVal === 0 && treeDataOne.length > 0 &&
<Tree
checkable
onExpand={onExpand}
// expandedKeys={expandedKeys}
// 修改2
defaultExpandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={treeDataOne}
defaultExpandAll={true}
/>
}
{typeVal === 1 && treeDataTwo.length > 0 &&
<Tree
checkable
onExpand={onExpand}
// expandedKeys={expandedKeys}
// 修改2
defaultExpandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={treeDataTwo}
defaultExpandAll={true}
/>
}
</div>
</div>
);
};
export default App;