我正在尝试在React中构建TreeNode函数,以构建某些数据的树结构。
我以虚假数据为起点:
const fakeData = {
"1234": {
id: "1234",
name: "Division",
address: "string",
childNodes: []
}
};
当我用“ id” 1234扩展“ Division”节点时,我想获取该节点的子级。因此,我的fakeData扩展为以下内容:
我正在使用fetch()方法获取数据,但是我不确定如何将该数据传递到Promise的resolve()方法。现在我正在这样做:
function fakeAjax(url, id) {
return new Promise((resolve, reject) => {
fetch(url)
.then(res => res.json())
.then(result => {
const nodes = result.map(node => node.id);
resolve(fakeData[id].childNodes.map(nodes));
});
});
}
function fetchChildNodes(id) {
return fakeAjax(`someUrl`, id);
}
function TreeNode({ id, name }) {
const [childNodes, setChildNodes] = useState(null);
// Toggle our display of child nodes
const toggleExpanded = useCallback(() => {
fetchChildNodes(id)
.then(nodes => setChildNodes(nodes.map(node => <TreeNode {...node} />)))
}
}, [childNodes]);
但是,这并未将相关的数据传递给resolve方法。我在做错什么吗?
答案 0 :(得分:2)
几件事跳了起来
您的代码正在使用explicit promise creation anti-pattern。 history.push(`/Viewchange?id=${record.id}&dataid=${record.dataid}`);
返回了一个承诺,无需在其周围包裹fetch
。这不是问题,但这是 a 问题,尤其是因为new Promise
的编写方式,如果ajax调用失败,则fakeAjax
返回的promise永远不会被拒绝(并且永远不会实现,它会永远待命)。
您正在调用fakeAjax
并传入一个非函数作为映射函数:
map
那没有任何意义。 const nodes = result.map(node => node.id);
resolve(fakeData[id].childNodes.map(nodes));
// Here −−−−−−−−−−−−−−−−−−−−−−−−−−−−^
接受一个函数,而不是一个数组。
您的代码正被map
API中的“脚枪”击中,几乎其他所有人也都受到了打击:您需要检查该请求是否在HTTP级别上起作用。 fetch
仅在出现网络错误而不是HTTP错误(我的博客here上有更多错误)时拒绝。
我假设您的ajax调用返回的实际节点数据应该直接传递给fetch
,而不进行修改(当然也不会变成仅包含TreeNode
值的数组)。
类似这样:
id
在function fetchJSON(url) {
return fetch(url)
.then(res => {
if (!res.ok) {
throw new Error("HTTP error " + res.status);
}
return res.json();
});
}
function fetchChildNodes(id) {
return fetchJSON(`someUrl`, id);
}
中发生了节点数据到TreeNode
的映射,因此我认为您不需要在TreeNode
中做任何事情。