Build a curtain menu with React!
Tags: html, css, react, tutorial
Published: 2021-11-08 14:05:09

Hey **fellow creators**,

You want to build a *curtain menu* for your app? You're in the right place!
 
If you prefer to watch the video **version**, it's right here :

{%youtube CORlOIl2tGE%}

Check out the source code to see which folders and files you need to recreate a **curtain menu** [here](https://github.com/Ziratsu/curtain-menu/blob/main/src/Components/CurtainMenu/CurtainMenu.js).

This will have a pretty simple design but you can change it up however you like!

##1. Create your component.
Create a simple React app and add a components folder in which you'll create your component CurtainMenu, in which you'll create two buttons and your links:

```react
import React, { useState, useEffect } from "react";
import "./CurtainMenu.css";
import Menu from "./menu.svg";

export default function CurtainMenu() {
  return (
    <>
        <button className="floating-btn">
          <img src={Menu} />
        </button>

      <nav>
          <button className="close-curtain">
            X
          </button>

        <a href="#">HOME</a>
        <a href="#">SERVICES</a>
        <a href="#">CONTACT</a>
      </nav>
    </>
  );
}
``` 

##2. Create some state.
Now let's create some state. It'll start with false since we want to see the nav only if we click on the button.

Then let's create another state that'll check the width of the window when you open the app and whenever you resize it.

```react
const [toggleNav, setToggleNav] = useState(false);

const [checkWidth, setCheckWidth] = useState(window.innerWidth);
```

##3. Use the *useEffect* hook!
Create a function that'll check the width of your window, which you'll use in your event listener:

```react
const checkFunc = () => {
    console.log(checkWidth);
    setCheckWidth(window.innerWidth);
  };

useEffect(() => {
    window.addEventListener("resize", checkFunc);

    return () => {
      window.removeEventListener("resize", checkFunc);
    };
  }, []);
``` 

The return function in the useEffect is necessary if, for some reason, your component is destroyed, it'll clean things up. 

##4. Hide the button if the window is large.
Add a condition so that the buttons only show if the window is under 900px.

```react
return (
    <>
      {checkWidth < 900 && (
        <button className="floating-btn">
          <img src={Menu} />
        </button>
      )}

      <nav className={toggleNav ? "active" : ""}>

        {checkWidth < 900 && (
          <button className="close-curtain">
            X
          </button>
        )}

        <a href="#">HOME</a>
        <a href="#">SERVICES</a>
        <a href="#">CONTACT</a>
      </nav>
    </>
  );
``` 

##5. But the button doesn't work... so let's add an *onClick* function!
Start by creating the function:

```react
const toggleNavFunc = () => {
    setToggleNav(!toggleNav);
  };
``` 

And then add it to your buttons:
```react
<button onClick={toggleNavFunc} className="floating-btn">
	<img src={Menu} />
</button>
```

and

```react
<button onClick={toggleNavFunc} className="close-curtain">
 X
</button>
``` 

It's still not working... That's because you need to change the classname of the name conditionally:

```react
<nav className={toggleNav ? "active" : ""}>
``` 

So if it's true, it'll show the nav otherwise it won't show.

##6. You're done!
That's it! Here's the full code of your component:
```react
import React, { useState, useEffect } from "react";
import "./CurtainMenu.css";
import Menu from "./menu.svg";

export default function CurtainMenu() {
  const [toggleNav, setToggleNav] = useState(false);

  const [checkWidth, setCheckWidth] = useState(window.innerWidth);

  const checkFunc = () => {
    console.log(checkWidth);
    setCheckWidth(window.innerWidth);
  };

  useEffect(() => {
    window.addEventListener("resize", checkFunc);

    return () => {
      window.removeEventListener("resize", checkFunc);
    };
  }, []);

  const toggleNavFunc = () => {
    setToggleNav(!toggleNav);
  };

  return (
    <>
      {checkWidth < 900 && (
        <button onClick={toggleNavFunc} className="floating-btn">
          <img src={Menu} />
        </button>
      )}

      <nav className={toggleNav ? "active" : ""}>

        {checkWidth < 900 && (
          <button 
          onClick={toggleNavFunc} className="close-curtain">
            X
          </button>
        )}

        <a href="#">HOME</a>
        <a href="#">SERVICES</a>
        <a href="#">CONTACT</a>
      </nav>
    </>
  );
}
``` 

You now have a nice **curtain menu** that you can customise however you want!


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


*See you soon !*

Enzo.