0

I'm still beginner with JavaScript and ReactJS.

I'm doing a project to improve my knowledge. I have a layout with CSS and HTML already responsive. I'm trying to implement some logic wiht Javascript on my ReactJS project. When I click on my burger-icon, my nav open up, and when I click on my close icon, my nav close up. Can you tell me how can i do this?

As the layout is responsive only in HTML and CSS, for my nav to appear, it depends on the width of the screen.

enter image description here

Here's my code I put into codesandbox.io

import React, { useState } from "react";
import "./index.scss";

const Home = () => {
  const [showMenu, setShowMenu] = useState(false);

  const handleBurgerIcon = (e) => {
    e.preventDefault();

    setShowMenu(!showMenu);
  };

  return (
    <div className="flex-container">
      <nav className="nav-categories">
        <div className="header">
          <h2>Categories</h2>
          <div className="close">
            <svg width="1em" height="1em" viewBox="0 0 12 12">
              <g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
                <g
                  transform="translate(-318.000000, -363.000000)"
                  fill="#000000"
                  fillRule="nonzero"
                >
                  <path
                    d="M318.234315,373.616648 C317.921896,373.929067 317.921892,374.435597 318.23432,374.748025 C318.54673,375.060434 319.053273,375.060443 319.365691,374.748025 L329.548029,364.565687 C329.860447,364.253269 329.860438,363.746726 329.548029,363.434316 C329.235601,363.121888 328.729071,363.121892 328.416652,363.434311 L318.234315,373.616648 Z M319.365688,363.234318 C319.05327,362.921899 318.546746,362.921889 318.234318,363.234318 C317.921908,363.546727 317.921899,364.05327 318.234318,364.365688 L328.416655,374.548026 C328.729074,374.860445 329.235617,374.860435 329.548026,374.548026 C329.860454,374.235598 329.860445,373.729074 329.548026,373.416655 L319.365688,363.234318 Z"
                    fill="currentColor"
                  />
                </g>
              </g>
            </svg>
          </div>
        </div>
        <ul className="nav-menu">
          <li className="active">
            <a href="#">Floral</a>
          </li>
          <li>
            <a href="#">Fresh</a>
          </li>
          <li>
            <a href="#">Gourmand</a>
          </li>
          <li>
            <a href="#">Woody</a>
          </li>
        </ul>
      </nav>
      <section className="perfumes-list">
        <header>
          <div className="burguer-button" onClick={handleBurgerIcon}>
            <div></div>
            <div></div>
            <div></div>
          </div>
          <input type="text" placeholder="Search by perfume" />
        </header>
        <ul>
          <li>
            <div className="perfume-item">
              <div className="box-info">
                <div className="box-info--content">
                  <div className="description">
                    <h1>Kim Kardashian</h1>
                    <p>
                      In 2009, Kim Kardashian launched a perfume line with her
                      signature fragrance, called Kim Kardashian by Kim
                      Kardashian.
                    </p>
                  </div>
                  <div className="tags">
                    <span>Woody</span> / <span>Oriental</span> /{" "}
                    <span>Gourmand</span>
                  </div>
                </div>
                <div className="box-info--footer">
                  <ul>
                    <li>
                      <span>Sample</span>{" "}
                      <h3>
                        Free<sup></sup>
                      </h3>
                    </li>
                    <li>
                      <span>Normal</span>{" "}
                      <h3>
                        38.00<sup>€</sup>
                      </h3>
                    </li>
                  </ul>
                </div>
              </div>
            </div>
          </li>
        </ul>
      </section>
    </div>
  );
};

export default Home;
:root {
  --white: #ffffff;
  --black: #111116;
  --gray: #f4f7f6;
  --gray-dark: #6c7680;
  --orange: #ff8f32;
}

body,
html {
  font-family: Helvetica, sans-serif;
  font-weight: 300;
  line-height: 1.5;
  color: var(--black);
  text-align: left;
  background-color: var(--gray);
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

ul {
  list-style-type: none;
}

p {
  color: var(--gray-dark);
}

.tags {
  color: var(--orange);
  text-align: right;
}

h1 {
  color: var(--orange);
  font-weight: 400;
}

h2 {
  font-size: 2.125rem;
  padding: 0 1rem;
}

h3 {
  font-size: 1.5rem;
  padding: 0 0.5rem;
  font-weight: 300;
}

.flex-container {
  display: flex;
  flex-flow: row wrap;
  text-align: center;
  max-width: 1400px;
  margin: 2rem auto;
}

.flex-container > * {
  padding: 15px;
  flex: 1 100%;
}

header {
  display: flex;
  align-items: center;
  text-align: center;
  margin-bottom: 2rem;
}

.burguer-button {
  margin-right: 1rem;
  cursor: pointer;
}

.burguer-button div {
  width: 2rem;
  height: 0.25rem;
  background-color: var(--black);
  margin-bottom: 0.3rem;
}

input[type="search"],
input[type="text"] {
  font-size: 1rem;
  font-weight: 300;
  background-clip: padding-box;
  transition: all 0.2s ease;
  outline: 0;
  -webkit-appearance: none;
  width: 100%;
  resize: none;
  padding: 1rem;
  border: 1px solid var(--gray);
}

input:hover,
input:focus {
  transition: all 0.2s ease;
  cursor: auto;
  border: 1px solid var(--orange);
}

.nav-menu .active a {
  color: var(--orange);
}

.nav-menu a {
  position: relative;
  display: block;
  padding: 1rem;
  font-size: 17px;
  font-weight: 300;
  color: #202121;
  cursor: pointer;
  background: #f4f7f6;
  border-bottom: 1px solid #e6eaea;
  text-decoration: none;
  transition: all 0.3s ease;
}

.nav-menu a:hover {
  background-color: var(--white);
  -webkit-transition: background 0.3s ease-in-out;
  transition: background 0.3s ease-in-out;
}

.perfume-item {
  position: relative;
  width: 100%;
  -webkit-transition: background 0.3s ease-in-out;
  transition: background 0.3s ease-in-out;
  box-shadow: 0 2px 3px 0 #e8ebed, 0 0 3px 0 #e8ebed;
}

.box-info {
  transition: all 0.3s ease-in-out;
  padding: 1.5rem;
  flex: 1;
  position: relative;
  clear: both;
  background-color: var(--white);
  margin-bottom: 1.5rem;
}

.box-info--content {
  display: flex;
  justify-content: space-between;
  margin-bottom: 1.5rem;
}

.box-info--footer {
  display: flex;
}

.box-info--footer ul {
  display: inline-flex;
}

.box-info--footer li {
  display: inline-flex;
  align-items: baseline;
  padding: 0 1rem 0 0;
}

.box-info--footer li span {
  color: var(--gray-dark);
}

/*Nav Categories*/
.nav-categories {
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  width: 75%;
  padding-top: 3rem;
  text-align: left;
  z-index: -1;
  background-color: var(--gray);
}

.nav-categories .header {
  position: relative;
}

.nav-categories .close {
  position: absolute;
  top: 0;
  right: 0;
}

.nav-categories ul {
  list-style-type: none;
}

.nav-categories li {
  cursor: pointer;
}

.nav-categories li.selected {
  background-color: rgb(87, 87, 206);
  color: #ffffff;
}

.perfumes-list {
  flex: 1;
  order: 2;
  text-align: left;
}

.perfume {
  margin: 10px;
  text-align: left;
  border-bottom: 1px solid black;
}

.perfume ul {
  list-style-type: none;
}

/*Pagination*/
.pagination {
  text-align: center;
  order: 3;
}

.pagination {
  width: 100%;
}

.pagination {
  display: inline-flex;
  align-items: center;
  padding-left: 0;
  margin-bottom: 0;
  justify-content: center;
}

.pagination li {
  margin-right: 0.25rem;
}

.pagination li:last-child {
  margin-right: 0;
}

.pagination li a {
  transition: all 0.3s ease-in-out;
  color: var(--gray-dark);
  padding: 0.375rem 0.4375rem;
  text-decoration: none;
}

.pagination li a:hover {
  background: var(--orange);
  color: var(--white);
}

.pagination li a:focus {
  box-shadow: inset 0 0 0 2px var(--orange);
}

.pagination li a:active {
  background: var(--gray-dark);
  color: var(--white);
}

.pagination .active a {
  background: var(--orange);
  color: var(--white);
  pointer-events: none;
}

// 48em -> 768px
@media (min-width: 48em) {
  .nav-categories {
    width: 40%;
  }
}

// 64em -> 1024px
@media (min-width: 64em) {
  .nav-categories {
    position: relative;
    top: unset;
    left: unset;
    display: block;
    width: 100%;
    flex: 0;
    order: 1;
    padding-top: 1rem;
    z-index: 0;
    display: block;
  }

  .nav-categories .close {
    display: none;
  }

  .burguer-button {
    display: none;
  }
}

Thank you advance!!

1 Answer 1

0

First of all you cannot just use class attribute in react. In react it's className. Click here for more info.

Handling events with React elements is very similar to handling events on DOM elements. There are just some syntax differences.

You can simply add an onClick listener to your burger-icon element and call a function that you create in your Home.js, like this.

<div className="burguer-button" onClick={handleBurgerIcon}>

Now we are going to create a boolean state and change the value everytime when button is clicked. This is how you create a state in a functional react.

const [showMenu, setShowMenu] = React.useState(false);

You can represent this like a variable with a getter and setter. And as default value we use false.

Now we create the function to handle the click.

const handleBurgerIcon = (e) => {
  e.preventDefault();

  setShowMenu(!showMenu);
}

The function setShowMenu toggles the value of our showMenu state.

Finally we use a conditional rendering for our nav-menu. So it only gets visible, when our showMenu is true. This is how you can do it.

{showMenu &&
  <ul className="nav-menu">
    <li className="active">
      <a href="#">Floral</a>
    </li>
    <li>
      <a href="#">Fresh</a>
    </li>
    <li>
      <a href="#">Gourmand</a>
    </li>
    <li>
      <a href="#">Woody</a>
    </li>
  </ul>
}
Sign up to request clarification or add additional context in comments.

4 Comments

Hey Enucar, unfortunately it didn't work, I put the css here now to help
It doesn't show, because your nav-menu is hidden in CSS. You can simply add conditional class name like show to nav-menu when the menu is visible and force in CSS nav-menu.show to display and position it how you want. You can add conditional class name like this. i.imgur.com/WS1hPwh.png
It should be !showMenu not showMenu in the example image.
Hey Enucar, I will try to apply what you said, but I must apply the logic in nav-categories, right ?! Instead of nav-menu?

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.