Search code examples
reactjssmooth-scrolling

Implementing smooth scrolling in react


I'm trying to create a website for myself and when you click on an image the page will scroll down to another element in a different section.

The structure of my code now is that I have an App class and in that class I make two other components, call them A and B.

class App extends Component{
   render () { 
      return (<A/>
              <B/>)
}

The image the user clicks is in component A and the element I want to scroll to is in B. I've tried to do this using the element.scrollIntoView function by creating a ref like so:

class App extends Component{
    constructor(props){
        super(props);

        this.divToFocus = React.createRef();
    }
    

    handleOnClick = () =>{
        this.divToFocus.scrollIntoView({behavior: 'smooth'}
    }

    render () {
        return (
        <div>
            <A click={this.handleOnClick}/>
            <B name={this.divToFocus} />
        </div>)}

and in A using the handleOnClick for the img onClick attribute (making sure to set "pointer-events": "all" for style)and then creating a div with the ref named this.divToFocus in B but got a type error saying this.divToFocus.scrollIntoView is not a function.

I also tried using react-scroll by doing something like this:

class A extends Component{
    render (){ 
        return (
        <Element name={"name"}>
            Hello world!
        </Element>
    )}
}

class B extends Component{
    render (){ 
        return (
        <Link activeClass="active" to="name" spy={true} smooth={true} offset={50} duration={500}>
          <img src={arrow} />
        </Link>
    )}
}

but then nothing happened when I would click on the image. Any advice about how to do this would be really appreciated!


Solution

  • You can use DOM and ScrollIntoView to achieve this.

    A.js

    import React from "react";
    
    export default function A() {
      const handleImageClick = () => {
        document.getElementById("myid").scrollIntoView({ behavior: "smooth" });
      };
      return (
          <img
            onClick={handleImageClick}
            alt="placeholder"
            src="https://via.placeholder.com/728x200.png?text=Visit+WhoIsHostingThis.com+Buyers+GuideC/O https://placeholder.com/"
          />
      );
    }
    
    

    B.js

    import React from "react";
    
    export default function B() {
      return (
        <div id="myid">
          <h1>Hello CodeSandbox</h1>
          <h2>Some Long content for scroll to happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
          <h2>Start editing to see some magic happen!</h2>
    
        </div>
      );
    }
    

    Codesandbox demo here