Almaron
Almaron

Reputation: 4147

ReactJS sortable dnd tree setup

React newbie again.

I have and admin page for a forum. It's a tree structure with potentially infinite depth, ordered by order_id field. I can get it from the api either as a tree (with a children array field holding the children of each node) or as a flat array with an ancestry (a string that holds the whole path to the node, separated by a /) and a parent_id field. I need to be able to move them around, expand and collapse subtrees and be able to add a node in any place.

Now I have several questions:

  1. Is there a good out-of-the-box UI library to be able to drag-drop them to rearrange? I found this one: https://github.com/frontend-collective/react-sortable-tree but I can't get it to not have a limited height frame, and also customizing those themes looks too complicated.

  2. If I am to do it from scratch using react-dnd, what is the more efficient way of working with this tree - have it as a tree (how do I add/update the nodes?) or store it flat and build the tree on render (easy to manage the collection, but complicates rendering and sorting logic).

Upvotes: 0

Views: 2158

Answers (1)

Rob Klein
Rob Klein

Reputation: 81

This sounds like a complicated and interesting problem. If the library cannot do what you want it to stylistically then you will have to build it from scratch.

I would store all of your node objects in an Array with a children property that holds a reference to all of it's children; you could use their order_id as a reference if it is guaranteed to be unique.

I would also store the parent node's order_id as well, as it will help when you manipulate the tree.

Nodes = [
  {order_id: 1, name:"order1", children_ids:[2,3], parent_id: 0},
  {order_id: 2, name:"order2", children_ids:[], parent_id: 1},
  {order_id: 3, name:"order3", children_ids:[], parent_id: 1},
]

You will have to build the tree on render, it may be a brain twister but it's more than doable with a bit of work.

When you add a new node, you will have to update the parent and children of it's new spot in the tree.

When you rearrange a node, you will have to travel up to the parent and remove it from it's children. You will also have to travel down to it's children and set their parents to the rearranged node's old parent. This removes the node from the tree. Then, add the rearranged node to the tree.

Any manipulation you do will involve manipulating the parent and children of that node - this is why I recommend storing both children's id and the parent's id. It saves you from having to do too many tree traversals which is not computationally efficient.

I don't recommend using an ancestry field as you mentioned. The logic for moving nodes around will be too complicated and you would have to traverse and edit potentially the entire tree if you do it this way.

The first step is to integrate with react-dnd; make each node draggable. When you drop it onto another node to rearrange, you trigger your rearrange handler.

Best of luck.

Upvotes: 1

Related Questions