1

I'm using the function in React for my Nav bar, and when the user clicks on one, it should automatically scroll to a certain part of the page. My code does this, but there's about a 1.5 second delay before it actually performs the action. How can I fix this?

This is my Navbar.js code:

import React from "react";
import { Link } from 'react-scroll';
import { FaBars, FaTimes } from 'react-icons/fa';
import { useState, useEffect } from "react";
import '../styles/Navbar.css';


const Navbar = () => {

  const [click, setClick] = useState(false);
  const handleClick = () => setClick(!click);
  const closeMenu = () => setClick(false);
  const [fix, setFix] = useState(false);

  const setFixed = () => {
    if (window.scrollY >= 950) {
      setFix(true);
    } else {
      setFix(false);
    };
  };

  window.addEventListener("scroll", setFixed);
  return (
      <div className={fix ? 'header active' : 'header'}>
          <nav className={fix ? 'navbar fixed' : 'navbar'}>
              <div className='hamburger' onClick={handleClick}>
                  {click ? (<FaTimes size={30} style={{ color: '#ffffff' }} />)
                      : (<FaBars size={30} style={{ color: '#ffffff' }} />)}
              </div>
              <ul className={click ? "nav-menu active" : "nav-menu"}>
                  <li className='nav-item'>
                    <Link to="header" spy={true} smooth={true} offset={-100} onClick={closeMenu} id="homeLink">Home</Link>
                  </li>
                  <li className='nav-item'>
                    <Link to="aboutMe" spy={true} smooth={true} offset={-100} onClick={closeMenu}>About</Link>
                  </li>
                  <li className='nav-item'>
                    <Link to="/" spy={true} smooth={true} offset={50} onClick={closeMenu}>Resume</Link>
                  </li>
                  <li className='nav-item'>
                    <Link to="/" spy={true} smooth={true} offset={50} onClick={closeMenu}>Projects</Link>
                  </li>
              </ul>
          </nav>
      </div>
  )
}

export default Navbar;

And this is my Navbar.css code, incase it's important at all:

.header {
  position: fixed;
  height: 90px;
  width: 100%;
  top: 0;
  left: 0;
  z-index: 1;
  transition: .3s ease-in;
  overflow: hidden;
  background-color: transparent;
}

.header.active {
  background-color: rgba(0,0,0,.9);
}

.header .navbar {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: auto;
  height: 100%;
  padding: 0 1rem;
}

.header .nav-menu a {
  color: #ffffff;
}

.header .nav-menu {
  display: flex;
}

.header .nav-item {
  padding: 1rem;
  font-weight: 500;
}

.header .nav-item a:hover {
  padding-bottom: 4px;
  color: #ffea00;
  border-bottom: 3px solid #ffea00;
}

.hamburger {
  display: none;
}

.nav-item {
  list-style: none;
}

#homeLink {
  text-decoration: none;
}

@media screen and (max-width:940px) {
  .header {
      max-width: 100%;
      background-color: rgba(0,0,0,.9);
  }

  .header .navbar {
      max-width: 100%;
      justify-content: space-between;
  }

  .hamburger {
      display: block;
  }

  .nav-menu {
      position: fixed;
      left: -100%;
      top: 90px;
      flex-direction: column;
      background-color: rgba(0,0,0,.9);
      width: 100%;
      height: 90vh;
      z-index: 999;
      text-align: center;
      transition: .3s;
  }

  .nav-menu.active {
      left: 0;
  }

  .nav-item {
      margin: 1.5rem 0;
  }

  .header .navbar img {
      width: 150px;
  }
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Sami
  • 69
  • 5
  • You've chosen smooth scrolling with `smooth={true}`, this will animate the scrolling effect. I don't see where you've specified any `delay` prop, so it's not clear from this code alone what is delaying the scrolling action. If you comment out `window.addEventListener("scroll", setFixed);` does this issue go away? Can you create a *running* [codesandbox](https://codesandbox.io/) demo that reproduces this issue that we could inspect live? – Drew Reese Sep 28 '22 at 02:41

1 Answers1

0

The only overt issue I see with this code is an unintentional side-effect. The code is adding a new scroll event listener each and every time the component rerenders, and never cleans any of them up. Each time a listener is added that is enqueuing React state updates is creating more and more work to do, and since the scroll event is extremely noisy it is likely generating copious amounts of unnecessary work.

Move the window.addEventListener logic into a useEffect hook and return a cleanup function to remove the event listener.

Example:

const [fix, setFix] = useState(window.scrollY >= 950);

useEffect(() => {
  const setFixed = () => {
    setFix(window.scrollY >= 950);
  };

  window.addEventListener("scroll", setFixed);

  return () => {
    window.removeEventListener("scroll", setFixed);
  };
}, []);

It might be more practical to just read the window.scrollY value when rendering and skip the fix state and listeners entirely.

Example:

const fix = window?.scrollY >= 950;

return (
  <div className={fix ? 'header active' : 'header'}>
    <nav className={fix ? 'navbar fixed' : 'navbar'}>
      ...
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • I tried both of those options and they didn't show any difference. When I do this exact same thing but with anchor tags, it works just fine, but its the tag that doesn't work properly. I do remember installing different packages from npm for other features, do you think maybe react is just confused because of the different installations? – Sami Sep 28 '22 at 03:21
  • @Sami I don't think React is confused. If there's a mixup in installed packages or imports then I expect expect either work, or not work, not something between. Can you create a [codesandbox](https://codesandbox.io/) demo that reproduces the issue we could take a look at? Can you also add your package.json file to the post so we see what versions of what are installed? – Drew Reese Sep 28 '22 at 05:19
  • @Sami I've copy/pasted your code into a [sandbox](https://codesandbox.io/s/why-is-react-router-link-taking-too-long-to-scroll-when-clicked-on-poseib) and I'm unable to reproduce any delays in scrolling action. – Drew Reese Sep 28 '22 at 06:45
  • I just copy and pasted to sandbox using the import from github tool on there and the problem still remains. Also, package.json won't fit here, so I'll post a link to the repository everything is saved under. Here is there is the package.json file: [repository](https://github.com/samisamara/personalWebpage) – Sami Sep 29 '22 at 04:33