我想做一个这样的表:
| --------
| - <Tr>
| + <Tr>
| - <Tr>
| - <Tr>
| - <Tr>
| <Tr>
| <Tr>
| <Tr>
| + <Tr>
| + <Tr>
表元素可以包含数千个子下拉元素。
我在React中编写代码,到目前为止我还不知道,也没有弄清楚如何以更优化的方式完成。
现在我正在尝试使用这样的数据结构
[
{
id: 1,
childrens: [
{ id: 10, childrens: [] },
{ id: 11, childrens: [{ id: 12, childrens: [] }] },
],
},
{ id: 2, childrens: [] },
];
当前实现思路:
当我点击下拉元素时,我做以下操作:
- 得到id
- 我正在寻找一个元素在数组id
- 我得到
childrens
的内容,如果数组包含数据,那么我将它们添加到父<tr>
元素后
要隐藏下拉<tr>
,我做以下操作:
- 得到id
- 我正在寻找一个元素在数组id
- 获取数组的长度
childrens
- 我删除父元素
<tr
之后,子元素<tr
的个数等于数组的长度
但是我不明白如何使用嵌套的子元素。为了不再次绕过整个数组,我需要以某种方式了解谁是谁的父元素。
我应该朝哪个方向探索这个问题?
我必须这样做一次,并使用递归解决它。创建您的表并在数据的第一个层上循环。
const TableDropdown = ({ data }) => {
return (
<table>
<tbody>
// loop over the first layer of data
{data.map((row) => (
<DropdownRow key={`dropdown-row-${row.id}`} row={row} />
))}
</tbody>
</table>
);
};
对于行
的实现- 在这一行中,我们设置一个状态来跟踪打开状态。
- 定义在打开和关闭之间切换的切换函数
- 最后确定我们是否有孩子,并检查下拉菜单是否打开。
const DropdownRow = ({ row }) => {
const [isOpen, setIsOpen] = useState(false);
// check whether the row has children
const hasChildren = row.childrens.length > 0;
// toggle the row
const toggleRow = () => {
// no need to toggle if no children
if (!hasChildren) return;
setIsOpen((prev) => !prev);
};
// create the child rows if the current row has children and is opened
const childRows =
hasChildren && isOpen
? row.childrens.map((childRow) => (
<DropdownRow key={`dropdown-row-${childRow.id}`} row={childRow} />
))
: null;
// just to determine which "icon" to display
const toggleIcon = !hasChildren ? "=" : isOpen ? "-" : "+";
return (
<>
<tr>
<td onClick={toggleRow}>{toggleIcon}</td>
<td>Row with id {row.id}</td>
</tr>
{childRows}
</>
);
};
点击这里查看实时版本