最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Render recursively a nested data in React - Stack Overflow

programmeradmin6浏览0评论

How would i go about rendering a menu with nested <ul> items with an an unknown amount of children in react from an object like in the following example?

[
  {
    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"
  }
]

How would i go about rendering a menu with nested <ul> items with an an unknown amount of children in react from an object like in the following example?

[
  {
    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"
  }
]
Share Improve this question edited Nov 16, 2017 at 5:39 Shubham Khatri 282k58 gold badges430 silver badges411 bronze badges asked Jul 24, 2017 at 17:35 SamuelSamuel 2,6356 gold badges34 silver badges41 bronze badges 4
  • Two questions: 1. Have you attempted to do this by yourself? 2. Is the depth of nesting a known factor? – Kyle Richardson Commented Jul 24, 2017 at 17:38
  • yes i've tried a few different things. I'm able to render the top level items using .map() but i cannot seem to get my head around how to render the children. I would ideally like the solution to be able to render children regardless of depth – Samuel Commented Jul 24, 2017 at 17:41
  • If you want to be able to traverse an object of unknown depth you will need to use recursion. You'll want to make a function that takes an object and an accumulator as an argument. The function will check for .children on the provided object and invoke itself with each child object as an the argument, don't forget the accumulator! If the provided object does not have a .children property it is a leaf node and you can generate you ponent with it's information. The accumulator is what the recursive function will used to build up the final collection as it goes. – Kyle Richardson Commented Jul 24, 2017 at 17:50
  • thanks! that makes sense - i guess my real question is how would i write such a function that conditionally stores ponents/markup that i can then return later in my ponent. In vanilla js, i would just store the markup as strings then output - however this approach doesnt seem to work in react. – Samuel Commented Jul 24, 2017 at 18:08
Add a ment  | 

2 Answers 2

Reset to default 14

Codesandbox example

You just have to recursively call Menu ponent for its children to display and pass as a data prop.

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>
);

You could recursively Render the ponent for nested data which has variable depth.

Sample Snippet.

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./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

P.S. The snippet contains formatting errors, but I am sure you will be able to rectify that. Snippet was to give an idea of the approach

发布评论

评论列表(0)

  1. 暂无评论