javascriptreactjsdrop-down-menureact-scroll

React-scroll navigate within the same page (dropdown menu)


I am trying to implement the navigation on my portfolio app using react-scroll, and it works fine until screen width changes and dropdown menu appears, since all of my components are rendered on the same page. It's pretty easy implementing react-router when I have multipage app, but this one really got me.

import { useRef } from "react";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React from 'react';
import { faBars, faCircleXmark } from '@fortawesome/free-solid-svg-icons';
import "./Navbar.css";
import {Link} from 'react-scroll';

function Navbar() {
    const navRef = useRef();

    const showNavbar = () => {
        navRef.current.classList.toggle(
            "responsive_nav"
        );
    };

    return (
        <header>
            <nav ref={navRef}>  
                <Link to="home" spy={true} smooth={true} offset={-100} duration={500}>Home</Link>
                <Link to="about" spy={true} smooth={true} offset={-100} duration={500}>About me</Link>
                <Link to="mywork" spy={true} smooth={true} offset={-100} duration={500}>My Work</Link>
                <Link to="contact" spy={true} smooth={true} offset={-150} duration={500}>Contact</Link>
                <button
                    className="nav-btn nav-close-btn"
                    onClick={showNavbar}>
                    <FontAwesomeIcon icon={faCircleXmark} style={{color: "#FFB30D",}} />
                </button>
            </nav>
            <button
                className="nav-btn nav-open"
                onClick={showNavbar}>
                <FontAwesomeIcon icon={faBars} style={{color: "#FFB30D",}}/>
            </button>
        </header>
    );
}

export default Navbar;
import './App.css'
import React from 'react';
import Navbar from "./Components/Navbar.jsx";
import Home from "./Components/Home.jsx";
import AboutMe from "./Components/AboutMe.jsx";
import MyWork from './Components/MyWork.jsx';
import Footer from './Components/Footer.jsx';
import { BrowserRouter } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Navbar />
      <Home />
      <AboutMe />
      <MyWork />
      <Footer />
    </BrowserRouter> 
  );
}

export default App

Once I click on the link in the dropdown menu, it does scroll to the chosen section, but the dropdown menu doesn't disappear.


Solution

  • Once I click on the link in the dropdown menu, it does scroll to the chosen section, but the dropdown menu doesn't disappear.

    Add an onClick handler that calls showNavbar to the links so when they are clicked on to scroll to the specific section they can also close the menu. I suggest also renaming showNavbar to something more accurate, like toggleNavbar since that is really what it does.

    function Navbar() {
      const navRef = useRef();
    
      const toggleNavbar = () => {
        navRef.current.classList.toggle(
          "responsive_nav"
        );
      };
    
      const linkProps = {
        onClick: toggleNavbar, // <-- add onClick handler
        spy: true,
        smooth: true,
        offset: -100,
        duration: 500,
      };
    
      return (
        <header>
          <nav ref={navRef}>  
            <Link to="home" {...linkProps}>Home</Link>
            <Link to="about" {...linkProps}>About me</Link>
            <Link to="mywork" {...linkProps}>My Work</Link>
            <Link to="contact" {...linkProps}>Contact</Link>
            <button
              className="nav-btn nav-close-btn"
              onClick={toggleNavbar}
            >
              <FontAwesomeIcon icon={faCircleXmark} style={{ color: "#FFB30D" }} 
     />
            </button>
          </nav>
          <button
            className="nav-btn nav-open"
            onClick={toggleNavbar}
          >
            <FontAwesomeIcon icon={faBars} style={{ color: "#FFB30D" }} />
          </button>
        </header>
      );
    }