How to scroll to top on every transition with React Router v5?

Sometimes, we want to scroll to top on every transition with React Router v5.

In this article, we’ll look at how to scroll to top on every transition with React Router v5.

Scroll to Top on Every Transition with React Router v5

To scroll to top on every transition with React Router v5, we can create a component that scrolls to the top every time we change routes and wrap that around the route components.

For instance, we can write:

import React, { useEffect } from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  withRouter
} from "react-router-dom";

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

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

const ScrollToTopWithRouter = withRouter(ScrollToTop);

const Foo = () => {
  return (
    <div>
      {Array(100)
        .fill()
        .map((_, i) => (
          <p key={i}>{i}</p>
        ))}
    </div>
  );
};

const Bar = () => {
  return (
    <div>
      {Array(100)
        .fill()
        .map((_, i) => (
          <p key={i}>{i}</p>
        ))}
    </div>
  );
};

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/foo">foo</Link>
          </li>
          <li>
            <Link to="/bar">bar</Link>
          </li>
        </ul>
        <ScrollToTopWithRouter>
          <Switch>
            <Route path="/foo" children={<Foo />} />
            <Route path="/bar" children={<Bar />} />
          </Switch>
        </ScrollToTopWithRouter>
      </div>
    </Router>
  );
}

We create the Foo and Bar components which we use as the route components.

Then we create the ScrollToTop component that listens for route changes with the history.listen method in the useEffect callback.

In the history.listen callback, we call window.scrollTo(0, 0) to scroll to the top when the route changes.

And we call the unlisten method in the function we return in the useEffect callback when the component unmounts.

We render the children components, which contains the route components.

Next, we call the withRouter function with ScrollToTop to return a component that we can wrap around the route components to listen for route changes.

Then in App, we add the Links and the Routes so that when we click the Links the components set as the values of Route‘s children prop would be rendered.

Therefore, each time we click on the links, we should see that the page is scrolled to the top.

Conclusion

To scroll to top on every transition with React Router v5, we can create a component that scrolls to the top every time we change routes and wrap that around the route components.