react-scroll | How to scroll to a specific targeted component when clicking on Navbar Link
Asked Answered
P

6

12

I am making a single scroller page using React and want to navigate to a specific section of the page. In HTML we use an href and anchor tag to achieve this interaction.

I found a React library called react-scroll but I do not know how to link each component in different folders from the a link in the NavBar component. My NavBar has multiple links for scrolling to a section/ component. Any help would really be appreciated!

  import React, { Component } from "react";
  import { Link, animateScroll as scroll } from "react-scroll";
  class Navbar extends Component {

    render() {
      return (
        <nav className="navbar navbar-expand-lg navbar-dark">
          <Link className="navbar-brand" to="/">
            CMD <span>Custom Movie Database</span>
          </Link>
          <button
            className="navbar-toggler"
            type="button"
            data-toggle="collapse"
            data-target="#navbarNav"
            aria-controls="navbarNav"
            aria-expanded="false"
            aria-label="Toggle navigation"
          >
            <span className="navbar-toggler-icon" />
          </button>
          <div className="collapse navbar-collapse" id="navbarNav">
            <ul className="navbar-nav">
              <li className="nav-item ">
                <Link
                  className="nav-link"
                  to="/"
                  spy={true}
                  smooth={true}
                  offset={-70}
                  duration={500}
                >
                  Home
                </Link>
              </li>
              <li className="nav-item">
                <Link
                  className="nav-link"
                  to="/"
                  spy={true}
                  smooth={true}
                  offset={-70}
                  duration={500}
                >
                  Search
                </Link>
              </li>
              <li className="nav-item">
                <Link
                  className="nav-link"
                  to="/"
                  spy={true}
                  smooth={true}
                  offset={-70}
                  duration={500}
                >
                  Category
                </Link>
              </li>
              <li className="nav-item">
                <Link
                  className="nav-link"
                  to="/"
                  spy={true}
                  smooth={true}
                  offset={-70}
                  duration={500}
                >
                  Popular
                </Link>
              </li>
              <li className="nav-item">
                <Link
                  className="nav-link"
                  to="/"
                  spy={true}
                  smooth={true}
                  offset={-70}
                  duration={500}
                >
                  Trailer
                </Link>
              </li>
              <li className="nav-item">
                <Link
                  className="nav-link"
                  to="/"
                  spy={true}
                  smooth={true}
                  offset={-70}
                  duration={500}
                >
                  Article
                </Link>
              </li>
              <li className="nav-item">
                <Link
                  className="nav-link"
                  to="/"
                  spy={true}
                  smooth={true}
                  offset={-70}
                  duration={500}
                >
                  Contact
                </Link>
              </li>
            </ul>
          </div>
        </nav>
      );
    }
  }

  export default Navbar;

This is Home Component where all component is added

    class Home extends React.Component {
      render() {
        return (
          <React.Fragment>
            <Navbar />
            <Showcase />
            <FormWrapper />
            <CategoryList />
            <MovieGrid />
            <MovieTrailer />
            <ArticleGrid />
            <Footer />
          </React.Fragment>
        );
      }
    }
Primate answered 15/2, 2019 at 18:52 Comment(0)
B
22

react-scroll is a great library - let me try and explain how I understand it.

Wherever I need a Link that scrolls to a certain element, I import that link, define it, and render it:

import React, { Component } from 'react'
import Scroll from 'react-scroll'
const ScrollLink = Scroll.ScrollLink

class Navbar extends Component {

render() {
  return (
    <nav>
      <ScrollLink 
        to="example-destination" 
        spy={true} 
        smooth={true} 
        duration={500} 
        className='some-class' 
        activeClass='some-active-class'
      >
        Link Text Goes Here
      </ScrollLink>       
    </nav>
  )
}

export default Navbar;

In a separate file, we define the destination that the `Link` will scroll to. The `Element` import from react-scroll makes this pretty easy!

import React, { Component } from 'react'
import { Element } from 'react-scroll'

export default function () {
  return (
    <React.Fragment>
    
      <Element id='example-destination' name='example-destination'>
        // wrap your content in the Element from react-scroll
      </Element>

    </React.Fragment>
  )
}

Making sense? Let me know if I can expand on this further!

Brail answered 15/2, 2019 at 19:22 Comment(2)
I wonder if we need id and name all the time.Popelka
The problem with this approach is that it doesn't work if you use responsive desing with smaller screens. Any one has a solution to that ? (using react-scroll of course)Swashbuckling
X
15

Other Alternative:

Put an id in component that you want to go:

<div id='some-id'>
</div>

After that, call from any place:

const anchor = document.querySelector('#some-id')
anchor.scrollIntoView({ behavior: 'smooth', block: 'center' })
Xenophobe answered 23/2, 2020 at 23:13 Comment(1)
This somewhat works on some of my pages but when it only contains about 3 elements, some of the elements get cutoff after the scrolling onto the target elementTupungato
E
3

Just building upon Diego Baranowski's solution. Made a onClick event listener for an element by clicking which your view is being scrolled down to the anchor element. Works just fine. I am a newbie so hopefully it does not defy React concept.

  <div 
     style={{"cursor":"pointer"}} 
     onClick={() => {
     const anchor = document.querySelector('#reviews-link')
     anchor.scrollIntoView({ behavior: 'smooth', block: 'center' })
    }}
  >
    <Rating
      rating={rating}
      numReviews={numReviews}
    ></Rating>
  </div>
Elianore answered 28/6, 2021 at 19:53 Comment(0)
A
0

A more React-friendly solution would be to get a reference to the element by using a "ref" (with useRef if it is a function component), instead of trying to access the DOM directly with document.querySelector.

Arbiter answered 16/12, 2022 at 13:5 Comment(0)
O
0

Another, simpler, approach would be to use a hash URL (aka fragment or anchor):

<a href="#some-id">Link</a>    
<div id="some-id">Some Content</div>

Clicking the link will automatically scroll you to the content. This way, the location will be 'saved' in the URL path, allowing for sharing or refreshing.

Ormazd answered 7/12, 2023 at 20:11 Comment(0)
I
0

Write a function to handle click event (handleClick). Pass the id of the element to which we need to scroll to the handleClick function. Then using the following code to perform the action.

  const handleClick = (id:string)=>{
  const elementID = document.querySelector(id);
  elementID?.scrollIntoView({ behavior: "smooth" })}

By using this the required functionality can be achieved without the help any external libraries.

Iaea answered 28/5, 2024 at 3:57 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.