【问题标题】:Recursively render a deep nested data in React在 React 中递归渲染深层嵌套数据
【发布时间】:2018-12-14 18:20:47
【问题描述】:

我是新手,我想在 sidenav 中渲染一个对象。我使用 map 函数循环遍历对象,但我得到map is not defined 错误。为我提供完整的 for 循环语法来呈现对象。

var side = ({
  "children": [
    {
      "children": [
        {
          "id": "b123a",
          "name": "compo"
        },
        {
          "id": "5a523",
          "name": "orient"
        },
        {
          "id": "42e7e",
          "name": "build"
        }
      ],
      "id": "f9ca7",
      "name": "building"
    },
    {
      "children": [
        {
          "id": "dbd4",
          "name": "insula"
        },
        {
          "id": "ad8404",
          "name": "fenest"
        },
        {
          "id": "e3837",
          "name": "window"
        }
      ],
      "id": "af776",
      "name": "envelope"
    },
    {
      "children": [
        {
          "id": "ba515",
          "name": "heating"
        },
        {
          "id": "6618",
          "name": "cooling"
        },
        {
          "id": "4a0547b8f",
          "name": "water_heating_system"
        }
      ],
      "id": "3e967",
      "name": "systems"
    },
    {
      "id": "e7c6e",
      "name": "spatial"
    },
    {
      "id": "9f641",
      "name": "design"
    }
  ],
  "name": "root"
})

而我的html代码是

<li>
                <a className="sidenav-title" href="#"><img src="/assets/img/primary/cube.png" style={{width: '20px',marginRight:'10px'}} />
                  <span>Building Form</span>
                </a>
                <a className="collapsible-header arrow-r">
                  <i className="fa fa-angle-down rotate-icon"></i>
                </a>
                <div className="collapsible-body">
                  <ul className="">
                    <li><a href="#" className="">Orientation</a></li>
                    <li><a href="#" className="">Volume</a></li>
                    <li className="li_hover_dropdown">
                      <div className="dropright posti-rel">
                        <a className="sidenav-title1 " href="#">Components</a>
                        <a className="nav-link arrow-r" href="#" style={{padding:'0px'}} data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                          <i className="fa fa-angle-right" style={{marginLeft: '25px'}}></i>
                        </a>
                        <div className="dropdown-menu sidenav-side">
                          <a style={{height:'0px'}}></a>
                          <a className="dropdown-item" href="#">Wall Type</a>
                          <a className="dropdown-item" href="#">Roof Type</a>
                          <a className="dropdown-item" href="#">Substructure Type</a>
                        </div>
                      </div>
                    </li>
                  <li><a href="#" className="">Glazing Size</a></li>
                  <li><a href="#" className=" fadein-color" style={{color:'rgba(0,0,0,34%)!important'}}>Shading Design</a></li>
                </ul>
              </div>
            </li>

在我的 sidenav 中,我使用了三种类型的菜单。第一个父级处于正常视图中,第二个子级处于向下打开的下拉菜单中,第三个菜单是一个向右打开的下拉菜单。

【问题讨论】:

标签: reactjs


【解决方案1】:

您需要递归地呈现您的数据。在最初的顶级渲染对象是这样的

const side = {
  "children": [
    {
      "children": [
        {
          "id": "b123a",
          "name": "compo"
        },
        {
          "id": "5a523",
          "name": "orient"
        },
        {
          "id": "42e7e",
          "name": "build"
        }
      ],
      "id": "f9ca7",
      "name": "building"
    },
    {
      "children": [
        {
          "id": "dbd4",
          "name": "insula"
        },
        {
          "id": "ad8404",
          "name": "fenest"
        },
        {
          "id": "e3837",
          "name": "window"
        }
      ],
      "id": "af776",
      "name": "envelope"
    },
    {
      "children": [
        {
          "id": "ba515",
          "name": "heating"
        },
        {
          "id": "6618",
          "name": "cooling"
        },
        {
          "id": "4a0547b8f",
          "name": "water_heating_system"
        }
      ],
      "id": "3e967",
      "name": "systems"
    },
    {
      "id": "e7c6e",
      "name": "spatial"
    },
    {
      "id": "9f641",
      "name": "design"
    }
  ],
  "name": "root"
}

const SideMenu = ({data}) => {
  if(!data) {
      return null;
  }
  return (
    <ul>
      {
      Array.isArray(data)? data.map(item => {
        return (<li>
          {item.name}
          {item.children && <SideMenu data={item.children} />}
        </li>);
      }): <li>
          {data.name}
          {data.children && <SideMenu data={data.children} />}
        </li>
      }
    </ul>
  );
}

ReactDOM.render(<SideMenu data={side} />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"/>

【讨论】:

  • 嗨,如果它有第三个孩子,你能解释一下吗?
  • @niranchan,你说的第三个孩子是什么意思
  • 嗨,我想为第一个孩子使用不同的类名,为第二个和第三个孩子使用不同的类名
  • @niranchan 您可以使用地图的索引属性来检查子位置。 data.map((item, index) => index === 0 || index === 1 ... rest)
  • 你应该先检查data 是否是undefined,然后再检查它是否是Array - 未定义会在该行产生错误
【解决方案2】:

我用上面的结果做出了回答,请利用它,

    <div className={level === 3 ?'collapsible-body':'' || level === 4 ?"dropdown-menu sidenav-side":''}>
<ul className={level === 2?'collapsible collapsible-accordion side-nav-link': ""}>
  {
  Array.isArray(data)? data.map(item => {
    return (
      <li className={level === 3?'li_hover_dropdown dropright posti-rel':''}>
        <a  className={level === 2?'sidenav-title':'' ||(level=== 3 && item.children)?"sidenav-title1":''} href="#"><img src={level === 2?'/assets/img/primary/cube.png':""} style={{width: '20px',marginRight:'10px'}} />
          <span>{item.name}</span>
        </a>
        <a className={level === 2   ?'collapsible-header arrow-r':'' || (level === 3 && item.children)?"nav-link arrow-r":'hidden-side'}>
            <i className={level === 2  ?'fa fa-angle-down rotate-icon':'' || (level=== 3 && item.children)?"fa fa-angle-right":'hidden-side'}></i>
        </a>
            {item.children && <SideMenu data={item.children} level={level+1}/>}
      </li>);
    }):
      <li>
        {data.name}
        {data.children && <SideMenu data={data.children} level={level+1}/>}
      </li>
  }
</ul>

侧边菜单是

<SideMenu data={side} level={1} />

【讨论】:

    猜你喜欢
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2019-04-08
    相关资源
    最近更新 更多