javascript - 获取异步 TreeView 数据
问题描述
我是新来的反应,我正在构建一个TreeView
反应组件,我在节点扩展时获取数据。我正在使用 Material UI 中的 TreeView:https ://material-ui.com/api/tree-view/
我创建了一个组件,它在扩展节点时在下面获取数据。MyTreeItem 是一个自定义版本,通过 fetch 调用扩展了原始版本。但我对如何显示子节点感到困惑。我怎样才能做到这一点?
import ReactDOM from "react-dom";
import React from "react";
import TreeView from "@material-ui/lab/TreeView";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import TreeItem from "@material-ui/lab/TreeItem";
const { useState, useCallback } = React;
export default function MyTreeItem({ id, name }) {
const [childNodes, setChildNodes] = useState(null);
const [expanded, setExpanded] = React.useState([]);
function fakeAjax(url) {
return fetch(url).then(res => {
if (!res.ok) {
throw new Error("HTTP error " + res.status);
}
return res.json();
});
}
function fetchChildNodes(id) {
// Should in reality be "URL/id", but fake JSON for now
return fakeAjax(`https://api.myjson.com/bins/1aqhsc`);
}
const handleChange = (event, nodes) => {
const expandingNodes = nodes.filter(x => !expanded.includes(x));
setExpanded(nodes);
if (expandingNodes[0]) {
const childId = expandingNodes[0];
fetchChildNodes(childId).then(result =>
setChildNodes(result.children.map(node => <MyTreeItem {...node} />))
);
}
};
return (
<TreeView
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
expanded={expanded}
onNodeToggle={handleChange}
>
{/*The node below should act as the root node for now */}
<TreeItem nodeId="1" label="Applications">
{/*The childnodes should be here*/}
</TreeItem>
</TreeView>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyTreeItem />, rootElement);
解决方案
在您的示例中,您似乎正在尝试构建树,其中每个具有子节点的节点也将是一棵树。
在这种情况下,渲染将如下所示:
{/*The node below should act as the root node for now */}
<TreeItem nodeId={props.id} label={props.name}>
{childNodes || [<div key="stub" />]} // stub div is used so user could see expand icon
</TreeItem>
// you also need to pass props for root items
ReactDOM.render(<MyTreeItem id="1" name="Applications" />, rootElement);
您可以在此处查看工作代码:https ://codesandbox.io/s/material-demo-k5ol6
有多种渲染树的方法。一种是对树结构进行建模并以某种方式对其进行渲染,这样每个具有子节点的节点将不再是具有本地状态的另一棵树,就像在您的实现中一样。这种方法的优点是您可以通过道具提供完整的树,而不仅仅是通过“扩展”操作来获取它。
这是这种方法的示例:https ://codesandbox.io/s/material-demo-h6zfe
此外,您可以将树渲染为列表,其中每个嵌套级别都有一个通过样式指定的偏移量。当您需要分别在每个级别上进行分页时(如果单个级别有很多项目),这具有优势。实现并不像上面的例子那么容易,所以我不会提供一个例子。
推荐阅读
- boto3 - 文件未使用 python 上传到 ibm 云对象存储出现错误
- vue.js - Vue路由器如何在进入外部域之前触发导航守卫
- entity-framework-core - 未找到方法 Microsoft.EntityFrameworkCore.Metadata.Builders.IndexBuilder onmodelcreating
- python - ModuleNotFoundError:没有名为“bs4”的模块,但在 Python 3.8.5 上使用 PIP3 正确安装
- javascript - 当我将变量作为文档参考传递时无法获取文档快照
- google-sheets - 谷歌表计时公式
- c++ - C++在有序链表中搜索节点
- javascript - 在 REACTJS 中渲染时出现周期性错误
- azure - Azure 应用程序网关 WAF_V2 ARM 部署失败
- jquery - 通过 https 调用在 localhost 上运行的 Owin 服务