如何在react中使用递归函数调用,返回一些数组?

时间:2017-09-02 18:07:36

标签: javascript node.js reactjs

我有一个列表(树结构)。节点(list item)可以包含任意数量的嵌套子节点。我必须根据给定的输入搜索节点(item)。结果应显示搜索到的节点(item)及其子节点。下面是代码。

import React from 'react';
import axios from 'axios';
let gTree = [];
class TreeView extends React.Component {
  constructor(){
     super();
     this.printChild = this.printChild.bind(this);
     this.recursiveSearch = this.recursiveSearch.bind(this);
     this.noResultFound = this.noResultFound.bind(this);
     this.processPattern = this.processPattern.bind(this);
     var userTreeViewList = {
        tree: [
          {
            "node": {
              "id": "1",
              "description": "test1",
              "children": [
                  {
                   "node": {
                        "id": "1_1",
                        "description": "test1_1",
                        "children": [
                            {
                             "node": {
                                  "id": "1_1_1",
                                  "description": "test1_1_1",
                                  "children": [
                                      {
                                       "node": {
                                            "id": "1_1_1_1",
                                            "description": "test1_1_1_1",
                                            "children": [

                                            ]
                                        }
                                      }
                                  ]
                              }
                            }
                        ]
                    }
                  },
                  {
                    "node": {
                      "id": "1_2",
                      "description": "test1_2",
                        "children": []
                    }
                  }
              ]
            }
          },
          {
            "node": {
              "id": "2",
              "description": "test2",
              "children": [
                  {
                   "node": {
                        "id": "2_1",
                        "description": "test2_1",
                        "children": [
                          {
                           "node": {
                                "id": "2_1_1",
                                "description": "test2_1_1",
                                "children": [

                                ]
                            }
                          }
                      ]
                    }
                  },
                  {
                    "node": {
                         "id": "2_2",
                         "description": "test2_2",
                         "children": [
                           {
                            "node": {
                                 "id": "2_2_1",
                                 "description": "test2_2_1",
                                 "children": [

                                 ]
                             }
                           }
                       ]
                     }
                   }
              ]
            }
          }
        ]
      };
     this.state = {
       userTreeViewList: userTreeViewList.tree, tempUserTreeViewList: userTreeViewList.tree
     }

  }


  printChild(children){
     return(    
       children.map( (item, i)=> {
          return <ul>
          <li>{item.node.description}</li>
          {item.node.children.length>0 ? this.printChild(item.node.children): null}
          </ul>
       })  
     )
  }

  processPattern(){
    //it removes * from end of patten and returns
    var pattern= this.refs.myInput.value;
    var len = pattern.length
    if(pattern[len-1] === '*')
    pattern = pattern.substring(0, len-1);
    return pattern;
  }

  recursiveSearch(children){
    //itsearch recursively the children for the pattern, and returns if found 
    var pattern= this.processPattern();
    var tree = [];
    if(children && children.length > 0){
      children.forEach( (item) => {
         item.node.description.includes(pattern) ? tree.push(item) : this.recursiveSearch(item.node.children);
      });
    } 
    return tree;
  };

  NameSearch(){
    //on seachButton click this is called
    var pattern= this.processPattern();
    if(pattern)
    var filteredUsers = [];
    this.state.userTreeViewList.forEach( (item)=>{
      if(item.node.description.includes(pattern)){
        filteredUsers.push(item);
        //;
      }
      else if(item.node.children.length>0){
        var res = this.recursiveSearch(item.node.children); 
        if(res.length>0 ) 
          filteredUsers=res;
      }
    })


    this.setState({  userTreeViewList: this.state.userTreeViewList, tempUserTreeViewList: filteredUsers  });

  }

  noResultFound(){
    if(this.state.tempUserTreeViewList.length===0)
      return(
        <div className="alert alert-danger">
          <span>No result found</span>
        </div>
      )
  }


   render() {


      return (
        <div>
            <h3>Tree View Search</h3>
            <hr />
            <div className="row">
                <div className="col-md-5"> 
                      <div className="input-group">
                        <input type="text" 
                              ref="myInput" 
                              className="form-control" 
                              placeholder="Search for..." 
                        />
                        <span className="input-group-btn">
                          <button className="btn btn-success" type="button" onClick={this.NameSearch.bind(this)}>
                            <span className="glyphicon glyphicon-search"></span> Search
                          </button>
                        </span>
                      </div>
                      {this.noResultFound()}

                </div>  
            </div>    



          <ul>
            {
                this.state.tempUserTreeViewList.map( (item, i)=>{
                  return( 
                    <li key={i}>
                        {item.node.description}
                        {item.node.children.length > 0 ? this.printChild(item.node.children): null}
                    </li>
                  )
                }) 
            }
          </ul>         
      </div>
    );
  }
}


export default TreeView;
当我输入test enter image description here

时,

我的搜索结果

当我输入test1_1时,我的结果是 enter image description here

当我输入test2_1时,我的结果是 enter image description here

  

但是当我输入test1_1_1test2_1_1时,我的结果是空的,但数据是否存在 enter image description here

1 个答案:

答案 0 :(得分:0)

你的算法在这些行中存在问题

children.forEach( (item) => {
  item.node.description.includes(pattern) ? tree.push(item) : this.recursiveSearch(item.node.children);
});

当三元运算符为false时,进入下一级递归,启动一个新的tree数组,然后开始匹配子节点。完成此匹配后,返回tree,但它不会存储到父tree数组中,因此内部递归结果将被丢弃。

修改您的代码应该可行。

item.node.description.includes(pattern) ? tree.push(item) : (tree = tree.concat(this.recursiveSearch(item.node.children)));

但总的来说,你可以努力改进算法。这看起来很漂亮。