4

I have XML parsed as JSON. I want to build a React component tree by traversing the JSON and calling React.createElement on each node. The third argument to React.createElement is an array of child React elements. This means that I have to walk down the tree to the leaf nodes, create those React elements first, and then walk back up each branch.

Simple, recursive iteration over a tree structure is simple enough. I'm unsure how to say "okay, now you're at the leaf node, go back up". Are there techniques for this?

Sample data:

{  
   "section":{  
      "attrs":{  
         "class":"foo",
         "data-foo":"foo"
      },
      "#name":"section",
      "children":[  
         {  
            "attrs":{  
               "class":"region-1"
            },
            "#name":"p",
            "children":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  },
                  "#name":"span"
               }
            ],
            "span":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  }
               }
            ]
         },
         {  
            "attrs":{  
               "class":"second"
            },
            "#name":"div"
         }
      ],
      "p":[  
         {  
            "attrs":{  
               "class":"region-1"
            },
            "children":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  },
                  "#name":"span"
               }
            ],
            "span":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  }
               }
            ]
         }
      ],
      "div":[  
         {  
            "attrs":{  
               "class":"second"
            }
         }
      ]
   }
}
maxhallinan
  • 1,259
  • 2
  • 14
  • 28

2 Answers2

5

In general, you can use this algorithm. I used other data for clarity. Your application-specific code goes in place of the console.log statement. For robustness, I added a test for the existence of a children property, and altered the data to test it.

var data = {
    name: 'Parent',
    children: [{
            name: 'Child 1',
            children: [{
                    name: 'Child 1a',
                    children: []
                }, {
                    name: 'Child 1b'
                }
            ]
        }, {
            name: 'Child 2',
            children: [{
                    name: 'Child 2a',
                    children: []
                }, {
                    name: 'Child 2b',
                    children: []
                }
            ]
        }
    ]
};

walk(data);

function walk(node) {
    if (node.children !== undefined) {
        node.children.forEach(function(child) {
            walk(child);
        });
    }

    console.log(node.name);
}
Kent Weigel
  • 1,168
  • 1
  • 11
  • 16
2

You have already solved half your problem, since you know that you should use recursion to iterate through the tree. But instead of rendering the node as soon as you get to it, render it only at the end of the recursive stack, or after processing all children. This is something like in-order traversal for binary trees.

function iterate(node) {
   if (node.children) {
      node.children.forEach(function (child) {
         iterate(child);
      });
   }

   console.log(node);
}

iterate(section);
Irvin Lim
  • 2,393
  • 17
  • 20