Home > Software design >  Recursion returns parent but not child
Recursion returns parent but not child

Time:06-21

I am starting to learn React and do not understand, why it works like this? I expect get element with name:'Node2', but I get parent with name:'Node1'. I have some tree

jsonNodes: [{
                id: 1,
                name: 'Node1',
                nodes: [
                    {
                        id: 2,
                        name: 'Node2',
                        nodes: [
                            {
                                id: 5,
                                name: 'Node5',
                                nodes: null,
                            }],
                    }, {
                        id: 4,
                        name: 'Node4',
                        nodes: null,
                    }],
            },
            {
                id: 3,
                name: 'Node3',
                nodes: null,
            }]

and some recursion method

getSelectedNode(nodes) {
        return nodes.find(element => {
            if (element.name == this.state.selectedItem)
            {
                return element;
            }
            else if (element.nodes != null)
            {
                return this.getSelectedNode(element.nodes);
            }
            else
            {
                return null;
            }
        });
    }

What is my mistake?

CodePudding user response:

You are not using find properly. If you return anything truthy in its callback, it will return the current element.

this.getSelectedNode(element.nodes) will eventually return the right element, but it will be treated as a truthy value, and it will mean that no matter what you do, the first element will be returned if any of it's descendants it's a match.

What you want to do is something like this:

getSelectedNode(nodes) {
  // Use a for loop instead of forEach to avoid nested functions
  // Otherwise "return" will not work properly
  for (const element of nodes) {
    // Check if this element is the seleted one, return it if it is
    if(element.name === this.state.selectedItem) {
       return element
    }

    // If it's not - recursively check its descendants, if it has any
    if(element.nodes){
      const found =  this.getSelectedNode(element.nodes)

      if(found){
       return found
      }
    }
  }

  // didn't find anything, return null
  return null
}
  • Related