基于嵌套数组渲染嵌套元素

时间:2018-12-11 10:52:57

标签: arrays node.js reactjs nested

我得到了这个嵌套数组,我需要遍历它来创建嵌套容器。 lvl4应该放在lvl3内,lvl3lvl2,而lvl2应该放在lvl1内。

const elements = [ 
  { name: 'a-lvl1', innerEl: [ 
    { name: 'a1-lvl2', innerEl: [
      { name: 'a1-lvl3' , innerEl: [ 
        { name: 'a-lvl4', innerEl: [] }
      ] },
      { name: 'a2-lvl3' , innerEl: [ 
        { name: 'a-lvl4', innerEl: [] }
      ] }
    ] },
    { name: 'a2-lvl2', innerEl: [
      { name: 'a-lvl3' , innerEl: [ 
        { name: 'a-lvl4', innerEl: [] }
      ] }
    ] },
    { name: 'a3-lvl2', innerEl: [
      { name: 'a-lvl3' , innerEl: [ 
        { name: 'a-lvl4', innerEl: [] }
      ] }
    ] },
  ] },
  { name: 'b-lvl1', innerEl: [ { }] },
  { name: 'c-lvl1', innerEl: [ { }] }
]

这是当前的脚本,正在运行,但是我正在寻找更简单的解决方案。

let renderElements = null;

if( elements !== undefined || elements.length != 0 ) {
  renderElements = elements.map( lvl1 => {   
    let lvl2Blocks = null;

    if( lvl1.innerEl !== undefined || lvl1.innerEl.length != 0) {
      lvl2Blocks = lvl1.innerEl.map( lvl2 => {
        let lvl3Blocks = null;

        if( lvl2.innerEl !== undefined || lvl2.innerEl.length != 0) {
          lvl3Blocks = lvl2.innerEl.map( lvl3 => {
            let lvl4Blocks = null;

            lvl4Blocks = lvl3.innerEl.map( lvl4 => {
              return (
                <div name={lvl4.name} selected={null} > 
                  { lvl4.innerEl !== undefined && lvl4Blocks }
                </div>
              )
            });

            return (
              <div name={lvl3.name} selected={null} > 
                { lvl3.innerEl !== undefined && lvl4Blocks }
              </div>
            )
          });
        }

        return (
          <div name={lvl2.name} selected={null} > 
            { lvl2.innerEl !== undefined && lvl3Blocks }
          </div>
        )
      });
    }

    return (
      <div name={lvl1.name} selected={null} > 
        { lvl1.innerEl !== undefined && lvl2Blocks }
      </div>
    )
  });
}

有什么想法吗?谢谢。

1 个答案:

答案 0 :(得分:1)

如已显示的here,我在Codesandbox中为您创建了一个可行的解决方案

同样,诀窍是在此处使用递归。因此,通过这个简单的组件,您将能够根据需要深度渲染。

function ListItem({ item }) {
  let children = null;
  if (item.innerEl && item.innerEl.length) {
    children = (
      <ul>
        {item.innerEl.map(i => (
          <ListItem item={i} key={i.id} />
        ))}
      </ul>
    );
  }

  return (
    <li>
      {item.name}
      {children}
    </li>
  );
}

但是请记住,您需要修复数据结构。如果您的数组应该为空,则不要在其中放置空对象:

{ name: 'b-lvl1', innerEl: [ { }] },

看起来应该是这样,或者您需要修改ListItem组件以检查第一项是否为空对象

{ name: 'b-lvl1', innerEl: [] },