I have the below function in order to recursively display IP subnets by user click:
const traverse = (o: any) => {
return o.map((item: any, key: number) => {
let extra = item.hasOwnProperty("extra") ? item.extra : item;
return (
<TreeItem
key={key}
nodeId={extra.id}
icon={item.has_child ? <ChevronLeftIcon /> : ""}
label={item.subnet}
onClick={
extra.has_child ? (e) => loadChildren(extra, extra.id) : () => ""
}
>
{item.child ? traverse(item.child) : ""}
</TreeItem>
);
});
};
Now I have put the fetch action in loadChildren where I would set the newly fetched data:
const loadChildren = (extra: any, id: number | string) => {
setLoadingChildren(true);
getIpState(id)
.then((res) => {
setRows({
...rows,
data: rows.data.map((item: any) =>
item.id == id ? { ...item, child: res.data } : item
),
});
setLoadingChildren(false);
})
.catch((err) => {
console.log(err);
setLoadingChildren(false);
});
};
Now the question is, how can I iterate through child: res.data and add their own child: res.data having the response of newly fetched data?
Finally it was solved like this:
const findClickedItem = (items: any,res: any,id:any) => {
return items.map((item: any) => {
let extra = item.hasOwnProperty('extra') ? item.extra : item
return extra.id == id ? {
...item,
child: res.data
} : item.hasOwnProperty('child')
? {...item, child: findClickedItem(item.child, res, id)} : item
}
)
}
And is used in loadChildren like this:
const loadChildren = (id: number | string) => {
setLoadingChildren(true)
getIpState(id).then(res=> {
setRows({
...rows,
data: findClickedItem(rows.data, res, id)
})
setLoadingChildren(false)
}).catch(err => {
console.log(err)
setLoadingChildren(false)
})
}