Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to navigate to another page with a smooth scroll on a specific id with react router and react scroll

i am trying to make navBar that navigate to another page and scroll down to some id on this page

this is the navBar component for my protofolio whih have 3 links the Projects should go to Home and then scroll down to projects id in the Project section

import React, { Component } from "react";
import logo from "../../images/logo.png";
import { Link } from "react-router-dom";
import Scroll from "react-scroll";
import "./NavBar.css";
const ScrollLink = Scroll.Link;

class NavBar extends Component {
  render() {
    return (
      <div className="NavBar">
        <Link to="/" className="logo-container">
          <img className="logo" src={logo} alt="Mahboub logo"></img>
        </Link>
        <div className="Nav-links">

          <Link to="/">Home</Link>
          <ScrollLink
            className="navy"
            smooth={true}
            duration={500}
            to="projects"
          >
            projects
          </ScrollLink>

          <Link to="/">Contacts</Link>
        </div>
      </div>
    );
  }
}
export default NavBar;

here is the prjects component for project section in home page

function Projects() {
  return (
    <div className="Home-Projects">
      <Element id="projects">
        <h1>Projects</h1>
      </Element>
      <div className="Projects-container">
        <ProjectElement />
      </div>
    </div>
  );
}
like image 768
Ahmed Mahboub Avatar asked May 13 '20 15:05

Ahmed Mahboub


1 Answers

If "duration" parameter isn't of great importance for you and you have no problems with Hooks, I'd like to suggest solution as follows.

  • You get rid of Scroll component and use plain Link from RR in your NavBar like so

    <Link to="/#projects">projects</Link>
    
  • Since RR v5.1 Hooks was introduced. There is useLocation hook among them. Insert that hook at the very beginning of your Projects component like so:

    function Projects() {
    const location = useLocation()
    ...
    

When you hit Link from p.1, you get new location object of the form


    location = {
        ...
        pathname:"/",
        ...
        hash: "#projects"
    }

  • Call useEffect hook after useLocation like so:

    useEffect(()=> {
            if (location.hash) {
                let elem = document.getElementById(location.hash.slice(1))
                if (elem) {
                    elem.scrollIntoView({behavior: "smooth"})
                }
            } else {
            window.scrollTo({top:0,left:0, behavior: "smooth"})
            }
    }, [location,])

And thats it. As you can see, if there is no hash in your url, your page would scroll to the top. Use [locaton,] as useEffect dependency prevents form scrolling when your page component rerenders not because of location changes.

like image 169
DmitriyBelovol Avatar answered Oct 11 '22 19:10

DmitriyBelovol