Code a responsive navbar with React!
Tags: html, css, react, tutorial
Published: 2021-10-30 09:49:15

Hey **fellow creators**,

It's time to build an awesome *responsive navbar* with React!
 
If you prefer to watch the video **version**, it's right here :

{%youtube 8kPk7CTOQh4%}

##1. Build the Navbar component.
```react
import React from 'react'
import './Navbar.css'

export default function Navbar() {
  return (
    <nav>
      <ul className="list">
	      <li className="items">Home</li>
	      <li className="items">Services</li>
	      <li className="items">Contact</li>
	    </ul>
      <button className="btn">BTN</button>
    </nav>
  )
}
```

##2. Style the navbar in your CSS file.
Start by styling the navbar however you want (with your own color palette!). Make sure to center everything and to fix it to the top of the page. Here's how I did it:

```css
nav {
    position: fixed;
    top: 0;
    width: 100%;
    height: 50px;
    background: linear-gradient(45deg, rgb(156, 14, 156), midnightblue);
}

.list {
    list-style-type: none;
    background: linear-gradient(45deg, rgb(156, 14, 156), midnightblue);
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
}
.items {
    margin-right: 20px;
    font-size: 20px;
    text-transform: uppercase;
    color: #f1f1f1;
    cursor: pointer;
}

.btn {
    display: none;
    position: absolute;
    right: 10px;
    top: 7px;
    padding: 5px;
    color: #000;
    font-size: 18px;
}
``` 

Now, the important thing is to make it responsive (for mobile screens), so add a media query:

```css
@media screen and (max-width: 500px){
    .list {
        flex-direction: column;
        height: auto;
    }
    .items:nth-child(1){
        border-top: 1px solid rgba(255, 255, 255, 0.555);
        margin-top: 50px;
    }
    .items {
        width: 100%;
        border-top: 1px solid rgba(255, 255, 255, 0.555);
        text-align: center;
        margin-right: 0px;
        padding: 20px 0;
    }
    .btn {
        display: block;
    }
}
```

##3. Use React to have a smooth toggle menu!

Now it's finally time to use React! In your Navbar.js file, add to the top of the file the hooks you'll need: 

```react
import React, {useState, useEffect} from 'react'
```

Then, create the state, which will be false since we don't want to see the menu when we arrive on the website. Add a short circuit operator in your nav, before your list of links, so that if the toggle menu is true, it'll show the list, otherwise it'll hide it:

```react
export default function Navbar() {
  const [toggleMenu, setToggleMenu] = useState(false)

  return (
    <nav>
      {(toggleMenu && (
      <ul className="list">
      <li className="items">Home</li>
      <li className="items">Services</li>
      <li className="items">Contact</li>
    </ul>
      )}

      <button className="btn">BTN</button>
    </nav>
  )
}
``` 
You then need to create a function that will toggle the menu upon clicking on the button:

```react
const toggleNav = () => {
    setToggleMenu(!toggleMenu)
  }
```
Add said function to your button to trigger the animation:

```react
<button onClick={toggleNav} className="btn">BTN</button>
``` 

It works! However if you widen your screen, then it'll hide your links, which isn't something we want. To fix this, you'll need to add a const below the first one, that will detect the screen width:

```react
const [screenWidth, setScreenWidth] = useState(window.innerWidth)
``` 

Modify the condition returning the nav or not, like so:
```react
return (
    <nav>
      {(toggleMenu || screenWidth > 500) && (
      <ul className="list">
      <li className="items">Home</li>
      <li className="items">Services</li>
      <li className="items">Contact</li>
    </ul>
      )}

      <button onClick={toggleNav} className="btn">BTN</button>
    </nav>
  )
}
```

Now, when you widen your page, the navbar will be complete with your links at the top of the page!

##4. Add an event.
However, upon shrinking the page, it'll show the menu but you can no longer toggle it. In order to fix that, you need to add an event. Use the hook *useEffect*, which is triggered once the component has finished mounting, which will trigger that callback function.

Create a function that'll be called every time the window is shrunk or widened, thanks to the event listener you'll need to add right after:

```react
useEffect(() => {

    const changeWidth = () => {
      setScreenWidth(window.innerWidth);
    }

    window.addEventListener('resize', changeWidth)

  }, [])
```

Now, whenever the window size changes, it's updating the state of your component, so that it'll go from the larger navbar to your toggle menu.
Wait! You're almost done, but here's one last thing you need to add to your hook:

```react
useEffect(() => {

   ...

    return () => {
        window.removeEventListener('resize', changeWidth)
    }

  }, [])
```
This is **recommended**: you need to use a clean-up function. That way, if your component is destroyed (for whatever reason), it'll remove the event listener from the memory.

*There you go!* Check out the full code [here](https://github.com/Ziratsu/Responsive-React-Navbar) to have a **complete overview** of the component and its css.

Come and take a look at my **Youtube channel**: https://www.youtube.com/c/TheWebSchool


Enzo.