Open waliurjs opened 1 year ago
Yes, this is a good idea. I will create a demo with this as I have time.
This would be super helpful, thanks @jameskerr!
Any update on this?
@jameskerr brother, this is the last thing I need help with promise. Could you please guide me?
Here's a PR that was just submitted shows an example of manually creating all the handlers for the Tree.
https://github.com/brimdata/react-arborist/pull/172/files
When a node is clicked, in the click handler, you'll make your api call, update the data, and the tree will re-render.
Good luck!
@jameskerr the PR makes sense. I now know why my code wasn't working before. It'll be much easier to implement custom logics.
I have been able to achieve lazy loading.
I created a custom hook from #172.
I replaced const [data, setData] = useState<T[]>([])
in the hook with jotai atom to be able to read and update the tree data globally.
export const treeDataAtom = atom<any>([]);
const [treeData, setTreeData] = useAtom(treeDataAtom);
In my Node component, the tree update is adapted from Ant design dynamic children .
When the node is clicked, the tree data is updated and persisted to the atom. You can also load the children from an api.
function Node({ node, style, dragHandle }: NodeRendererProps<any>) {
const [treeData, setTreeData] = useAtom(treeDataAtom);
function updateTreeData(list, id, children) {
return list.map((nodeItem) => {
if (nodeItem.id === id) {
return { ...nodeItem, children };
}
if (nodeItem.children) {
return { ...nodeItem, children: updateTreeData(nodeItem.children, id, children) };
}
return nodeItem;
});
}
function loadChildren({ id, children }) {
return new Promise(resolve => {
if (children && children.length > 0) {
resolve();
return;
}
setTimeout(() => {
setData(origin =>
updateTreeData(data, id, [
{
id: `${id}-0`,
name: 'Child Node',
children: [],
},
{
id: `${id}-1`,
name: 'Child Good',
children: [],
},
]),
);
resolve();
}, 1000);
});
}
return (
<>
<div
style={style}
className={clsx(styles.node, node.state)}
ref={dragHandle}
onClick={() => loadChildren(node)}
>
<PageArrow node={node} />
<IconFileDescription size="18px" style={{ marginRight: '4px' }} />
<span className={styles.text}>
{ node.data.name }
</span>
</div>
</>
);
}
I am not sure if I am doing it the right way but so far it works.
Working Demo:
https://github.com/brimdata/react-arborist/assets/16838612/c8d36b88-41c6-480f-a56c-033945ada7ec
Related to #127
@Philipinho Would you be willing to share your code? 🥇 I'm working on an implementation right now, and would love to be able to share & compare 😊
Cheers!
@CHE1RON It was more of a POC incase I would need it in my application (not yet needed). Unless I would spend some time to create a working demo. Lets see.
for those that don't want to do a time out. There is another way as the timeout isn't 100% reliable.
I tried to use a flag in the Node Component with useState, but it would reset the state when the tree re-rendered.
i first tried this but this caused problems with it opening every time the node re rendered and reset the local State Inside the TreeNode Component back to initial.
useEffect(() => {
if (children && children.length > 0) {
node.open()
}
}, [children, children.length])
So I reached for the tree ref. and stored any nodes where I had finished lazy loading.
function Node({ node, style, dragHandle, setTree, tree }: any) {
...
useEffect(() => {
if (!tree?.store?.idsLoaded?.includes(_id) && node.isInternal) {
node.open()
tree.store.idsLoaded = [...(tree?.store?.idsLoaded ?? []), _id]
}
}, [node.isInternal, hasLoaded, tree])
...
}
hope this helps anybody trying this
https://github.com/brimdata/react-arborist/assets/32978225/7ba8246f-7f44-463b-9f89-271ecda9aadd
@CHE1RON not sure if this is still relevant to you.
This is the live implementation in my software. https://github.com/docmost/docmost/blob/df9110268c9059dd568afac8a74868e6a4815e30/apps/client/src/features/page/tree/components/space-tree.tsx#L132
Hook for mutating tree and syncing with backend: https://github.com/docmost/docmost/blob/df9110268c9059dd568afac8a74868e6a4815e30/apps/client/src/features/page/tree/hooks/use-tree-mutation.ts#L24
I am using Jotai to manage the tree data across components.
Happy to clear any doubts.
https://github.com/brimdata/react-arborist/assets/16838612/b11ca64b-4daa-4b75-bae4-0938bd778b80
Hi! This is related to #127 Lazy loading children when parent is opened.
Can you guys please provide a pattern/pseudo code or some advice on how to implement it?
What I can gather from the docs is that I think I need to have a controlled component like this. But I have more questions.
Some concerns that I need advice on:
id: string
without being nested likechildren: []
?Desperately need some advice or some pseudo codes.
Thank you!
(Found your HackerNews comment)