supersize
supersize

Reputation: 14833

What do values only in JS map mean and how to write it the long way

I understand that only passing values of an object to JS map function results in having the objects values as variables (works just fine)

{links.map(({ key, href, label }) => (
   <li key={key}>
     <Link href={href} />
   </li>
))}

but how does it actually look like when I want to write it without syntactic sugar?

My attempt so far

{links.map(link => ({ key = link.key, href = link.href }) => (
  <li key={key}>
    <Link href={href} />
  </li>
))}

but with the latter I'm getting:

Functions are not valid as a React child

I need to know how to deconstruct the syntactic sugar example because I have a nested object and I need to iterate through each of the nesting.

Upvotes: 1

Views: 59

Answers (2)

MrCode
MrCode

Reputation: 64536

I see you accepted an answer for the original question. In response to your question about handling sub links, take a look at this way. It supports multiple levels of sub links without having to repeat any code. This is useful if you don't know how many levels there are, for example in a menu or navigation.

Fiddle demo

The TreeList component:

const TreeList = (props) => {
  return (
    <ul>
      {props.links.map(link => (
        <li key={link.key}>
          <Link href={link.href} label={link.label} />
          {link.sublinks ? <TreeList links={link.sublinks}></TreeList> : null}
        </li>
      ))}
    </ul>
  )
}

Usage:

class App extends React.Component {

  render() {
    const links = [{ key:4, label: 'top', href: '/some-url'}, { key:1, label: 'one', href: '/some-url', sublinks: [{ key:2, href: "/hello", label: "hello", sublinks: [{ key:3, href: "/hello", label: "grandchild" }] }]} ];

    return <TreeList links={links}></TreeList>;
  }
}

Upvotes: 1

Sagiv b.g
Sagiv b.g

Reputation: 31024

Your second example returns an anonymous function on each iteration.

I think you wanted to do this:

{links.map(link => (
  <li key={link.key}>
    <Link href={link.href} />
  </li>
))}

Edit
Not sure what you realy want to do with nested objects.
But as per your example, here is a running code:

class App extends React.Component {
  state = {
    links: [
      {
        key: 'one',
        href: '/some-url',
        sublinks: [{
          href: "/hello",
          label: "hello"
        }]
      },
      {
        key: 'two',
        href: '/some-url2',
        sublinks: []
      }
    ]
  }
  render() {
    const { links } = this.state;
    return (
      <div>
        {links.map(link => (
          <div>
            <a href={link.href}>{link.key}</a>
            {link.sublinks &&
              link.sublinks.map(subLink => (
                <div>
                  <a href={subLink.href}>{subLink.label}</a>
                </div>
              ))}
          </div>
        ))}
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<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="root" />

Upvotes: 3

Related Questions