0

I'm trying to figure out the best ways of creating functional components that generate simple html - take this nav-links.js file for example:

export const navLinks = [
  {
    name: "home",
    href: "/"
  },
  {
    name: "subs",
    href: "/subs"
  }
];

The html my component attempts to generate just loops through each link to generate an unordered-list with list tags and a tags inside.

The problem occurs in this nav-menu.js file, where the output is just an two <ul></ul> tags with nothing inside:

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";
import {navLinks} from "../util/nav-links";

export const NavMenu = () => {
  const lis = () => (
    {navLinks}.map(link => {
      return (
        <li>
          <Link to={link.href} key={link.href}>{link.name}</Link>
        </li>
      )
    })
  )

  return (
    <div id="navbar">
        <ul>
          {lis}
        </ul>
      </div>
  )
}

Why is nothing rendering in the above component? I wrote some more code below that solves it, although I wonder whether it could be refactored better:

export const NavMenu = () => {
    return (
      <div id="navbar">
          <ul>
            {navLinks.map(link => {
              return (
                <li>
                  <Link to={link.href} key={link.href}>{link.name}</Link>
                </li>
              )
            })}
          </ul>
        </div>
    )
  }

Why does the first attempt not work, and how could it be better refactored? Thanks for any help here

2
  • 1
    What happens if instead of {lis} you use {lis()} or rename it to Lis (capital letter) and try <Lis />? Commented Sep 3, 2020 at 11:02
  • 1
    It didn't work first time, because you attempted to use Array.prototype.map() on Object (since you destructured your navLInks array into navLinks variable when you did import {navLinks} from "../util/nav-links", and then created an object {navLinks: [{name: 'home', href: '/'},{name: 'subs', href: '/subs'}]} when you wrapped navLinks into curly braces). So your first attempt, most probably, threw an error. It would work as expected if you skipped curly braces: navLInks.map(... Though, I would prefer second approach. Commented Sep 3, 2020 at 11:05

1 Answer 1

1

In your the first example didn't work because you passed the const list = () => {..} as a anonymous function without calling it, inside the curly braces in the JSX portion of you code.

If you have called it like {list()}:

return (
    <div id="navbar">
        <ul>
          {lis()}
        </ul>
    </div>
)

This way it would have probably worked.

Or you could have stored the list inside a variable like this:

const lis = navLinks.map(link => {
      return (
        <li>
          <Link to={link.href} key={link.href}>{link.name}</Link>
        </li>
      )
    }
)

or also like this:

const lis = navLinks.map(link => (
        <li>
          <Link to={link.href} key={link.href}>{link.name}</Link>
        </li>
      )
    )
)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.