1

I want to scroll to the top of the page after changing the route. However, when the user presses the "Back" button in the browser, I want them to return to the previous scroll position on the previous page and NOT to the top. I have implemented n "scroll to the top" feature and it works (Link). However, I am wondering how I need to modify it to remember the previous scroll position, when going "Back".

Scroll to Top:

import React, { useEffect, Fragment } from "react";
import { withRouter } from "react-router-dom";

function ScrollToTop({ history, children }) {
  useEffect(() => {
    const unlisten = history.listen(() => {
      window.scrollTo(0, 0);
    });
    return () => {
      unlisten();
    };
  }, []);

  return <Fragment>{children}</Fragment>;
}

export default withRouter(ScrollToTop);

App.js

<ScrollToTop>
   <Switch>
       <PublicRoute exact path="/join/" component={LandingPage} />
   </Switch>
</ScrollToTop>
dan_boy
  • 1,735
  • 4
  • 19
  • 50

1 Answers1

2

One way you can accomplish this is by tracking where the user is via the location key and the window x, y coords. react-router-dom gives a good idea here.

Here's an example of what that might look like.

export default function ScrollRestoration() {
  const { key } = useLocation();
  const positions = useRef(new Map());

  useEffect(() => {
    if (positions.current.has(key)) {
      const { x, y } = positions.current.get(key);
      window.scrollTo(x, y);
    } else {
      window.scrollTo(0, 0);
    }

    const handler = () => {
      positions.current.set(key, { x: window.scrollX, y: window.scrollY });
    };

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

  return null;
}

Demo: https://codesandbox.io/s/relaxed-aryabhata-u1hgf

Dennis Martinez
  • 6,344
  • 11
  • 50
  • 67
  • Thx dennis. i will check the code later in the evening. – dan_boy Apr 13 '21 at 15:54
  • Thanks it works well for the BrowserRouter but not for the HashRouter. how would it look for an HashRouter insetad of an BrowserRouter? – dan_boy Apr 14 '21 at 10:26
  • @dan_boy `HashRouter` doesn't support `location.key` which is the magic behind this approach. You'll probably want to look into `window.onhashchange` along with generating and keeping track of the key yourself. I'd recommend asking a new question specifically for this. – Dennis Martinez Apr 14 '21 at 12:17