【发布时间】:2020-08-06 17:03:56
【问题描述】:
我有一个 React 组件,它通过 HTML 端点从 REST API 检索对象数组(键值对):
[
{
"id": 1,
"grouping1": "first-level-node-1",
"grouping2": "second-level-node-1",
"theThing": "third-level-node-1",
"someData": "data here that is associated with theThing",
"someUrl": "http://someurl.com"
},
{
"id": 2,
"grouping1": "first-level-node-2",
"grouping2": "second-level-node-1",
"theThing": "third-level-node-1",
.
.
.
}
]
我正在尝试操纵 JSON 响应,以便使用 react-simple-tree-menu 显示它。要生成TreeMenu,需要以数组的形式提供数据:
// as an array
const treeData = [
{
key: 'first-level-node-1',
label: 'Node 1 at the first level',
..., // any other props you need, e.g. url
nodes: [
{
key: 'second-level-node-1',
label: 'Node 1 at the second level',
nodes: [
{
key: 'third-level-node-1',
label: 'Last node of the branch',
nodes: [] // you can remove the nodes property or leave it as an empty array
},
],
},
],
},
{
key: 'first-level-node-2',
label: 'Node 2 at the first level',
},
];
或作为一个对象:
// or as an object
const treeData = {
'first-level-node-1': { // key
label: 'Node 1 at the first level',
index: 0, // decide the rendering order on the same level
..., // any other props you need, e.g. url
nodes: {
'second-level-node-1': {
label: 'Node 1 at the second level',
index: 0,
nodes: {
'third-level-node-1': {
label: 'Node 1 at the third level',
index: 0,
nodes: {} // you can remove the nodes property or leave it as an empty array
},
},
},
},
},
'first-level-node-2': {
label: 'Node 2 at the first level',
index: 1,
},
};
我尝试根据 grouping1(第一级节点)和 grouping2(第二级节点)对 JSON 响应进行分类,使其“适合”到 treeData:
const fetchItems = async () => {
const data = await fetch('http://localhost:3001/stuff');
const input = await data.json();
const output = input.reduce((acc, item) => ({
...acc,
[item.grouping1]: {
...acc[item.grouping1],
[item.grouping2]: [
...(acc[item.gropuing1] && acc[item.grouping1][item.grouping2] || []),
item,
]
}
}), {})
现在我的对象 (grouping1) 包含包含键值对数组的对象 (grouping2)。
first-level-node-1:
second-level-node-1: Array(4)
0: {id: 1, grouping1: "first-level-node-1", grouping2: "second-level-node-1", theThing: "third-level-node-1"}
.
.
.
first-level-node-2:
second-level-node-1: Array(16)
0: {id: 2, grouping1: "first-level-node-2", grouping2: "second-level-node-1", theThing: "third-level-node-1"}
.
.
.
但这不是 react-simple-tree-menu 想要的 treeData 结构。如何按摩 JSON 响应以适应 treeData 结构?
这里有一个很好的write-up,介绍了如何在 React 中启动和运行侧边栏菜单,但没有任何内容说明如何获得典型的 JSON 响应以适应所需的结构。
更新:
以下是TreeMenu数据that controls this react-simple-tree-menu component
<TreeMenu
data={[
{
key: 'mammal',
label: 'Mammal',
nodes: [
{
key: 'canidae',
label: 'Canidae',
nodes: [
{
key: 'dog',
label: 'Dog',
nodes: [],
url: 'https://www.google.com/search?q=dog'
},
{
key: 'fox',
label: 'Fox',
nodes: [],
url: 'https://www.google.com/search?q=fox'
},
{
key: 'wolf',
label: 'Wolf',
nodes: [],
url: 'https://www.google.com/search?q=wolf'
}
],
url: 'https://www.google.com/search?q=canidae'
}
],
url: 'https://www.google.com/search?q=mammal'
},
{
key: 'reptile',
label: 'Reptile',
nodes: [
{
key: 'squamata',
label: 'Squamata',
nodes: [
{
key: 'lizard',
label: 'Lizard',
url: 'https://www.google.com/search?q=lizard'
},
{
key: 'snake',
label: 'Snake',
url: 'https://www.google.com/search?q=snake'
},
{
key: 'gekko',
label: 'Gekko',
url: 'https://www.google.com/search?q=gekko'
}
],
url: 'https://www.google.com/search?q=squamata'
}
],
url: 'https://www.google.com/search?q=reptile'
}
]}
debounceTime={125}
disableKeyboard={false}
hasSearch
onClickItem={function noRefCheck(){}}
resetOpenNodesOnDataUpdate={false}
/>
如果我理解正确的话,Mammal 是 first-level-node-1,而 Reptile 是 first-level-node-2。 Canidae 和 Squamata 在各自的一级节点下都是二级节点 1。 Dog、Fox 和 Wolf 分别是第三级节点 1、节点 2 和节点 3。 Lizard、Snake 和 Gekko 也是第三级 node-1、node-2 和 node-3。我在这篇文章顶部使用的示例可能会令人困惑。如果是这样,我很抱歉。
这是与我正在使用的数据更相似的 JSON 数据:
[
{
"id": 2,
"grouping1": "I124",
"grouping2": "Cross_Streets",
"theThing": "12th",
"url": "http://url2.com"
},
{
"id": 3,
"grouping1": "I124",
"grouping2": "Cross_Streets",
"theThing": "13th",
"url": "http://url3.com"
},
{
"id": 4,
"grouping1": "I124",
"grouping2": "Cross_Streets",
"theThing": "4th",
"url": "http://url4.com"
},
{
"id": 14,
"grouping1": "I124",
"grouping2": "Ramps",
"theThing": "Ramp_A",
"url": "http://url14.com"
},
{
"id": 15,
"grouping1": "I124",
"grouping2": "Ramps",
"theThing": "Ramp_B",
"url": "http://url15.com"
},
{
"id": 41,
"grouping1": "I75",
"grouping2": "Cross_Streets",
"theThing": "100th",
"url": "http://url41.com"
}
]
目标是让上面的 JSON 在 react-simple-tree-menu 中看起来像这样:
+ I124
+ Cross_Streets
12th
13th
4th
+ Ramps
Ramp_A
Ramp_B
+ I75
+ Cross_Streets
4th
【问题讨论】:
-
是不是应该只有三层以上?还有,应该算是一个等级吗?我看到
grouping1、grouping2和theThing但someData和someUrl不是?这些是应该被视为级别的键的确切名称吗? -
someData 和 someUrl 与分组没有任何关系。只是 grouping1、grouping2 和 theThing。抱歉,如果我没有说清楚。
-
@goto1
grouping1是最高级别(树中最左侧),一旦您展开它,它将显示其下的所有grouping2,然后theThing将显示在下面grouping2展开时。每个theThing都是独一无二的。someData和someUrl只是 JSON 响应中的附加值,当用户单击 theThing 时,我将对其进行处理。很抱歉造成混乱。 -
下面的解决方案能满足你的需要吗?
-
是的,我删除了它,因为我发现它有误,但后来修复了它,现在它又回来了,有两个结果,一个是
array,一个是object- 现在看看。跨度>
标签: arrays json reactjs javascript-objects