如何在React TypeScript中默认给每个TreeItem节点添加按钮?
给MUI TreeView的每个节点添加操作按钮
要给每个TreeItem节点添加默认操作按钮,核心是利用TreeItem的label属性支持自定义React元素的特性,将原本的文本标签替换为包含节点名称和按钮的容器即可。以下是修改后的完整代码:
import React, { useEffect, useState } from "react"; import TreeView from "@mui/lab/TreeView"; import TreeItem from "@mui/lab/TreeItem"; import ExpandMoreIcon from "@material-ui/icons/ExpandMore"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; // 新增导入按钮和图标组件 import IconButton from "@mui/material/IconButton"; import EditIcon from "@mui/icons-material/Edit"; import DeleteIcon from "@mui/icons-material/Delete"; import { useForm } from "react-hook-form"; interface FileNode { id: string; parentId: number; name: string; children?: readonly FileNode[]; } export const TreeViewFile = () => { const [data, setData] = useState<FileNode[]>([]); const [selectedNode, setSelectedNode] = useState<FileNode>({} as FileNode); const [selectedRoot, setSelectedRoot] = useState<FileNode>({} as FileNode); const [selectedOption, setSelectedOption] = useState(null as any); const [dropDownData, setDropDownData] = useState([] as any); useEffect(() => { fetch("https://localhost:44306/api/user/Getlistofchildren") .then((data) => data.json()) .then((data) => setData(data)); }, [selectedNode, selectedRoot]); const handleChange = (event: any, nodeId: string) => { data.forEach((treeRoot: FileNode) => { if (treeRoot.id === nodeId) { setSelectedRoot(treeRoot); setSelectedNode(treeRoot); return; } handleSelectedNode(treeRoot.children, treeRoot, nodeId); }); }; const handleSelectedNode = ( children: FileNode[] | undefined, treeRoot: FileNode, nodeId: string ) => { if (!children) { return; } for (let i = 0; i < children.length; i++) { let childNode = children[i]; if (childNode.id === nodeId) { setSelectedRoot(treeRoot); setSelectedNode(childNode); return; } handleSelectedNode(childNode.children, treeRoot, nodeId); } }; // 新增编辑按钮点击处理函数 const handleEdit = (node: FileNode) => { console.log("编辑节点:", node); // 这里添加你的编辑逻辑 }; // 新增删除按钮点击处理函数 const handleDelete = (node: FileNode) => { console.log("删除节点:", node); // 这里添加你的删除逻辑 }; const displayTreeView = (treeViewArray: FileNode[]) => { if (!treeViewArray) { return null; } return treeViewArray.map((treeViewItem) => { return ( <TreeItem key={treeViewItem.id} nodeId={`${treeViewItem.id}`} // 修改label为自定义组件,包含名称和操作按钮 label={ <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", width: "100%" }}> <span>{treeViewItem.name}</span> <div> <IconButton size="small" onClick={() => handleEdit(treeViewItem)}> <EditIcon style={{ color: "#1976d2" }} /> </IconButton> <IconButton size="small" onClick={() => handleDelete(treeViewItem)}> <DeleteIcon style={{ color: "#d32f2f" }} /> </IconButton> </div> </div> } > {displayTreeView(treeViewItem.children || [])} </TreeItem> ); }); }; return ( <> <TreeView onNodeSelect={handleChange} sx={{ height: 240, flexGrow: 1, maxWidth: 800, overflowY: "auto" }} defaultExpandIcon={<ChevronRightIcon />} defaultCollapseIcon={<ExpandMoreIcon />} > {displayTreeView(data)} </TreeView> </> ); };
关键修改说明:
- 导入组件:新增了
IconButton、EditIcon和DeleteIcon,用于实现操作按钮和图标显示。 - 自定义Label:将TreeItem的
label从单纯的文本替换为Flex布局的div,左侧显示节点名称,右侧显示两个操作按钮,通过justifyContent: "space-between"让元素两端对齐。 - 按钮样式:通过内联样式给图标设置蓝红颜色,对应你描述的标记按钮。
- 点击事件:添加了
handleEdit和handleDelete函数,接收当前节点数据,方便后续实现具体的编辑/删除逻辑。 - 类型优化:修正了
selectedNode和selectedRoot的类型定义,符合TypeScript规范。
内容的提问来源于stack exchange,提问作者Sigmo
相关产品推荐
相关产品推荐

