Rendering nav links with .map() in React.
Tags: tutorial, react, javascript
Published: 2020-06-24 17:21:07

React utilises `.map()` to render items in a list, this can be great for dynamically adding links to our navigation. Instead of copying the markup, again and again, ill run through how I have used `.map()` on my navigation.

If you don't know already my site is built on Gatsby a static site generator built on React. Gatsby’s `<Link>` component enables linking to internal pages as well as a powerful performance feature called preloading. 

In any situation where you want to link between pages on the same site, use the `Link` component instead of an `a` tag.

```javascript
// standard a tag
<a href="/posts">Posts</Link>

// Gatsby Link component
<Link to="/posts">Posts</Link>
```
### The basis of our navigation 

Let's start off by creating the foundation of our component.

```javascript
import React from 'react'
import { Link } from 'gatsby'

const Nav = () => {
	
	return()
}

export default Nav
```

### Styling our links

Now we have everything set up we can now add an object called `styles` this will allow us to use `className` and `activeClassName`

It’s often a good idea to show which page is currently being viewed by visually changing the link matching the current page. This can be done by using `activeClassName` — a class name that will only be added to the Link when the current item is active.

As I am using [TailWind](https://tailwindcss.com/) here, my styles object is going to look like this:

```javascript
const styles = {
        className:'text-gray-600 block px-2 py-1 hover:underline hover:text-gray-900',
        activeClassName: 'underline text-gray-900'
    }
```

We can then access those properties by dot notation as follows:
```javascript
styles.className
styles.activeClassName
```

### Generating Link data.

Now we have our styles in an object, we can now move on to the Link data we want to pass. This will be an array of objects allowing us to use `.map()` on the array.

```javascript
const links = [
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/projects',
            name: 'Projects'
        },
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/posts',
            name: 'Posts'
        },
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/contact',
            name: 'Contact'
        },
    ]
```
Above each object has 4 key pairings. 

-	__className__: Our link styles
-	__activeClassName__: Our styles for active links
-	__to__: The page we wish to link to once clicked
-	__name__: What we what our link to display on site

Our navigation component should now look something like this:

```javascript
import React from 'react'
import { Link } from 'gatsby'

const Nav = () => {
 
    const styles = {
        className:'text-gray-600 block px-2 py-1 hover:underline hover:text-gray-900',
        activeClassName: 'underline text-gray-900'
    }
    
    const links = [
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/projects',
            name: 'Projects'
        },
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/posts',
            name: 'Posts'
        },
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/contact',
            name: 'Contact'
        },
 
    ]

    return ( )
}

export default Nav
```

### Adding our data to our markup.

Within our return statement, we need a parent `<div>` so lets do that

```javascript
return(
	<div></div>
)
```
You can then build out your navigation bar how ever you like the next bit will be how to dynamically display the links. This can be done by using `.map()` on our links array of objects as below shows:

```javascript
<div>
	{links.map(link => (<Link className={link.className} activeClassName={link.activeClassName} to={link.to}>{link.name}</Link> ))}
 </div>
```

When using `.map()` we have to provide it with a callback function which will be passed every item in the `links` array. 

For the above example, our one required argument for our callback function is `link` which now allows us to access items on the links array by using dot notation again. If you were to check the Gatsby docs for `Link` you can see it should look something like this:

```
<Link className= activeClassName= to= ></Link>
```
Now this wouldnt do anything so we have to add the following to it so `map()` can populate it as so:

```
<Link className={link.className} activeClassName={link.activeClassName} to={link.to}>{link.name}</Link>
```

If you want to learn more about how `map()` works you can see that [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).


### Finished Item

Now we have that in place our navigation component should look like this:

```javascript
import React from 'react'
import { Link } from 'gatsby'

const Nav = () => {    
  
  const styles = {
        className:'text-gray-600 block px-2 py-1 hover:underline hover:text-gray-900',
        activeClassName: 'underline text-gray-900'
    }    const links = [
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/projects',
            name: 'Projects'
        },
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/posts',
            name: 'Posts'
        },
        {
            className: styles.className,
            activeClassName: styles.activeClassName,
            to: '/contact',
            name: 'Contact'
        },    
    ]    
    
    
    return (
      <div>
          <div>LOGO</div>
          <div>
         {links.map(link => (<Link className={link.className} activeClassName={link.activeClassName} to={link.to}>{link.name}</Link> ))}
         </div>
      </div>
    )
}
export default Nav

```

Hope this helps. You can see my navigation component [here](https://github.com/mrpbennett/gatsby-me/blob/master/src/components/nav.js "Link to Nav source code"), if you get stuck you can hit me up on Twitter.

### Learn more about map

- [Programming with Mosh. .map()](https://youtu.be/G3BS3sh3D8Q)
- [Part 2 of Functional Programming in JavaScript - Fun Fun Function](https://www.youtube.com/watch?v=bCqtb-Z5YGQ)

PS: If there is a better way to do navigation in React please let me know.