【问题标题】:Render recursively a nested data in React在 React 中递归渲染嵌套数据
【发布时间】:2018-05-11 14:02:35
【问题描述】:

我将如何渲染一个包含嵌套 <ul> 项目的菜单,其中未知数量的子项对对象做出反应,如下例所示?

[
  {
    title: "Top level 1",
    slug: "top-level-1",
    children: [
      {
        title: "Sub level 1",
        slug: "sub-level-1",
        children: [
          {
            title: "Sub Sub Level 1"
            slug: "sub-sub-level-1"
          }
        ]
      }
      {
        title: "Sub level 2",
        slug: "sub-level-2"
      }
    ]
  },
  {
    title: "Top level 2",
    slug: "top-level 2"
  }
]

【问题讨论】:

  • 两个问题: 1. 你有没有尝试过自己做这个? 2. 嵌套深度是已知因素吗?
  • 是的,我尝试了一些不同的方法。我可以使用.map() 渲染顶级项目,但我似乎无法理解如何渲染孩子。理想情况下,我希望解决方案能够在不考虑深度的情况下渲染儿童
  • 如果您希望能够遍历未知深度的对象,则需要使用递归。您需要创建一个以对象和累加器为参数的函数。该函数将在提供的对象上检查.children,并以每个子对象作为参数调用自身,不要忘记累加器!如果提供的对象没有 .children 属性,则它是叶节点,您可以使用其信息生成组件。累加器是递归函数用来构建最终集合的东西。
  • 谢谢!这是有道理的 - 我想我真正的问题是我将如何编写这样一个有条件地存储组件/标记的函数,然后我可以稍后在我的组件中返回。在 vanilla js 中,我只会将标记存储为字符串然后输出 - 但是这种方法似乎在反应中不起作用。

标签: javascript wordpress reactjs


【解决方案1】:

Codesandbox example

您只需要递归调用 Menu 组件以使其子组件显示并作为数据道具传递。

let data = [
  {
    title: "Top level 1",
    slug: "top-level-1",
    children: [
      {
        title: "Sub level 1",
        slug: "sub-level-1",
        children: [
          {
            title: "Sub Sub Level 1",
            slug: "sub-sub-level-1",
            children: [
              {
                title: "Sub Sub Level 2",
                slug: "sub-sub-level-2"
              }
            ]
          }
        ]
      },
      {
        title: "Sub level 2",
        slug: "sub-level-2"
      }
    ]
  },
  {
    title: "Top level 2",
    slug: "top-level 2"
  }
];

const Menu = ({data}) => {
  return (
    <ul>
      {data.map(m => {
        return (<li>
          {m.title}
          {m.children && <Menu data={m.children} />}
        </li>);
      })}
    </ul>
  );
}

const App = () => (
  <div style={styles}>
    <Hello name="CodeSandbox" />
    <h2>Start editing to see some magic happen {'\u2728'}</h2>
    <Menu data={data} />
  </div>
);

【讨论】:

  • 这太棒了,有没有一种简单的方法可以将 slug 道具传递给子组件以形成例如'top-level-1/sub-level-1/sub-sub-level-1 ' ?
【解决方案2】:

您可以递归地为具有可变深度的嵌套数据渲染组件。

示例片段。

var data = [
  {
    title: "Top level 1",
    slug: "top-level-1",
    children: [
      {
        title: "Sub level 1",
        slug: "sub-level-1",
        children: [
          {
            title: "Sub Sub Level 1",
            slug: "sub-sub-level-1"
          }
        ]
      },
      {
        title: "Sub level 2",
        slug: "sub-level-2"
      }
    ]
  },
  {
    title: "Top level 2",
    slug: "top-level 2"
  }
]

const MyComponent  = (props) => {
     if(Array.isArray(props.collection)) {
         return <ul>
               {props.collection.map((data)=> {
                   return <li>
                      <ul>
                        <li>{data.title}</li>
                        <li>{data.slug}</li>
                        <li><MyComponent collection={data.children}/></li>
                      </ul>
                   </li>
               })
               }
         </ul>
     }
     return null;
}

class App extends React.Component {
    render() {
        return (
           <MyComponent collection={data}/>
        )
    }
}

ReactDOM.render(<App/>, 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"></div>

附: sn-p 包含格式错误,但我相信您将能够纠正它。片段是为了给出方法的想法

【讨论】:

    猜你喜欢
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2016-06-20
    • 1970-01-01
    • 2020-09-24
    相关资源
    最近更新 更多