简体   繁体   中英

how to convert this code?? vanilla js to react.js

This is code
I want to use in react.. How to convert? When I run this code, It's failed, I think because of querySelector ..

--- i modify this code after answer and i add fontawesome but i can't see navbar in website what can i do? is this code have a problem with js, css connect? i wondering why cannot import navbar..

import React, { useState } from "react";
import "../css/Burger.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faArrowRight } from '@fortawesome/free-solid-svg-icons';
import { faArrowLeft  } from '@fortawesome/free-solid-svg-icons';

function Burger() {
  // create state to control the toggle state - so you can detect if nav is 
  //open or not
  const [navIsOpen, setNavIsOpen] = useState(false);

  //in this funciton we are toggeling true / false.
  const toggleNavHandler = () => {
    setNavIsOpen((prev) => !prev);
  };

  return (
    <div>
      <div
        className={`burger ${navIsOpen && "burger-open"}`}
        onClick={() => toggleNavHandler()}
      >
        <i><FontAwesomeIcon icon={faArrowRight} /></i>
        <i><FontAwesomeIcon icon={faArrowLeft} /></i>
      </div>

      <nav className={`navbar ${navIsOpen && "nav-open"}`}>
        <ul className="nav-links">
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">Home</a>
          </li>
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">Blog</a>
          </li>
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">Gallery</a>
          </li>
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">About</a>
          </li>
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">Contact</a>
          </li>
        </ul>
      </nav>
    </div>
  );
}

export default Burger;

this is burger.css

.navbar .nav-links li:nth-of-type(1), .navbar .nav-links li:nth-of-type(2), .navbar .nav-links li:nth-of-type(3), .navbar .nav-links li:nth-of-type(4), .navbar .nav-links li:nth-of-type(5) {
     opacity: 0;
     transition: 0.3s ease-in all;
}
 .navbar .nav-links li:nth-of-type(1).nav-link-open, .navbar .nav-links li:nth-of-type(2).nav-link-open, .navbar .nav-links li:nth-of-type(3).nav-link-open, .navbar .nav-links li:nth-of-type(4).nav-link-open, .navbar .nav-links li:nth-of-type(5).nav-link-open {
     opacity: 1;
     transform: translateY(10px);
}
 .navbar .nav-links li a::before, .navbar .nav-links li a::after {
     position: absolute;
     content: '';
     height: 4px;
     width: 0%;
     background-color: #2a3255;
     left: 0;
     border-radius: 2px;
     transition: 0.3s ease all;
}

 .burger {
     position: absolute;
     top: 25px;
     right: 25px;
     color: #23f0ff;
     cursor: pointer;
     z-index: 1;
     display: flex;
}
 .burger i:nth-of-type(1) {
     display: block;
}
 .burger i:nth-of-type(2) {
     display: none;
}
 .burger.burger-open {
     color: #2a3255;
}
 .burger.burger-open i:nth-of-type(1) {
     display: none;
}
 .burger.burger-open i:nth-of-type(2) {
     display: block;
}
 .navbar {
     position: absolute;
     top: 0;
     left: 0;
     height: 100%;
     width: 100%;
     background-color: #23f0ff;
     clip-path: circle(0px at 0 0px);
     transition: 0.5s ease all;
}
 .navbar .nav-links {
     position: absolute;
     top: 50%;
     left: 50%;
     transform: translate(-50%, -50%);
}
 .navbar .nav-links li {
     list-style-type: none;
     margin: 3rem 0;
}
 .navbar .nav-links li:nth-of-type(1).nav-link-open {
     transition-delay: 0.25s;
}
 .navbar .nav-links li:nth-of-type(2).nav-link-open {
     transition-delay: 0.35s;
}
 .navbar .nav-links li:nth-of-type(3).nav-link-open {
     transition-delay: 0.45s;
}
 .navbar .nav-links li:nth-of-type(4).nav-link-open {
     transition-delay: 0.55s;
}
 .navbar .nav-links li:nth-of-type(5).nav-link-open {
     transition-delay: 0.65s;
}
 .navbar .nav-links li a {
     text-decoration: none;
     color: #2a3255;
     font-size: 2.4rem;
     position: relative;
     text-transform: uppercase;
     letter-spacing: 1px;
}
 .navbar .nav-links li a::before {
     top: -2px;
}
 .navbar .nav-links li a::after {
     bottom: -5px;
}
 .navbar .nav-links li a:hover::before {
     width: 100%;
}
 .navbar .nav-links li a:hover::after {
     width: 100%;
}
 .navbar.nav-open {
     display: block;
     clip-path: circle(100%);
}
 

Something like this should do the work :

import React, {useState} from 'react';
import '../css/Burger.css';

function Burger() {

  const [isOpen, setIsOpen] = useState(false)
    
  const handleClick = () => {
      setIsOpen(prevState => !prevState)
  }
    

  return (
    <div>
      <div className={"burger"+ isOpen ? "burger-open" : ""} onClick={handleClick}>
        <i className="fas fa-bars fa-2x"></i>
        <i className="fas fa-times fa-2x"></i>
      </div>

      <nav className={"navbar" + isOpen ? "nav-open" : ""}>
        <ul className="nav-links">
          <li className="nav-link">
            <a href="#">Home</a>
          </li>
          <li className={"nav-link" + isOpen ? "nav-link-open" : ""}>
            <a href="#">Blog</a>
          </li>
          <li className={"nav-link" + isOpen ? "nav-link-open" : ""}>
            <a href="#">Gallery</a>
          </li>
          <li className={"nav-link" + isOpen ? "nav-link-open" : ""}>
            <a href="#">About</a>
          </li>
          <li className={"nav-link" + isOpen ? "nav-link-open" : ""}>
            <a href="#">Contact</a>
          </li>
        </ul>
      </nav>
    </div>
  );
}

export default Burger;

What i did here to make vanilla js to React.

First - you need to change class to className .

Second - create a state (with useState hook) to detect the change

Third - create click event on the element you want (the burger in this case) and create the handle. inside the handler you can see im switching (toggeling) between true and false by using prev . setState giving the previous state as argument by default. we are using it to toggle it with !

Fourth - insert in each element's class (className) detector to check if the nav is open or not. im using && operator , if the nav is open it will add the class, if not it will not show the class.

If you need more explaination or working example let me know...


UPDATED CODE:

import React, { useState } from "react";
import "./css/burger.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBars, faTimes } from "@fortawesome/free-solid-svg-icons";

function Burger() {
  // create state for each component that you want to control
  const [navIsOpen, setNavIsOpen] = useState(false);

  //in this funciton we are toggeling true / false in each state.
  const toggleNavHandler = () => {
    setNavIsOpen((prev) => !prev);
  };

  return (
    <div>
      <div className="burger" onClick={() => toggleNavHandler()}>
        {navIsOpen ? (
          <FontAwesomeIcon icon={faTimes} />
        ) : (
          <FontAwesomeIcon icon={faBars} />
        )}
      </div>

      <nav className={`navbar ${navIsOpen && "nav-open"}`}>
        <ul className="nav-links">
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">Home</a>
          </li>
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">Blog</a>
          </li>
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">Gallery</a>
          </li>
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">About</a>
          </li>
          <li className={`nav-link ${navIsOpen && "nav-link-open"}`}>
            <a href="#">Contact</a>
          </li>
        </ul>
      </nav>
    </div>
  );
}

export default Burger;


EDIT: To make font-awesome to work on your code you need to install 3 packages:

npm i --save @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/react-fontawesome

just copy and pase it in the terminal. it will install:

@fortawesome/fontawesome-svg-core
@fortawesome/free-solid-svg-icons
@fortawesome/react-fontawesome

after installing those 3 you need to import react-fontawesome and to import the icons you want to use:

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBars, faTimes } from "@fortawesome/free-solid-svg-icons";

To use the icons you need to use FontAwesomeIcon :

<FontAwesomeIcon icon={faTimes} />

Working example - codesandbox

If you find this answer helpful, please mark it as the answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM