Sometimes, we want our React app pages to scroll to the top on every transition.
In this article, we’ll look at how to make our React app pages to scroll to the top on every transition.
React Router Scroll to Top on Every Transition
We can create our own component to scroll to the top and wrap that around the component that we want to scroll to the top.
For instance, we can write:
class ScrollToTop extends Component {
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
window.scrollTo(0, 0)
}
}
render() {
return this.props.children
}
}
export default withRouter(ScrollToTop)
We call the withRouter
prop with the ScrollToTop
component.
Then we have the location
prop available in ScrollToTop
after that.
In the component, we check the location
prop to see what the path is in the componentDidUpdate
method.
If they’re different, that means we transitioned to a new route.
So we call window.scrollTo(0, 0)
to scroll to the top of the page.
In render
, we render the children
prop so that we display the content of it.
Then, to use it, we write:
import ScrollToTop from './ScrollToTop';
//...
const App = () => (
<Router>
<ScrollToTop>
<Foo />
</ScrollToTop>
</Router>
)
We wrap it our around Foo
component to scroll it to the top when it’s loaded.
Also, we can do the same thing with hooks.
For instance, we can write:
import { useEffect } from 'react';
import { withRouter } from 'react-router-dom';
function ScrollToTop({ history }) {
useEffect(() => {
const unlisten = history.listen(() => {
window.scrollTo(0, 0);
});
return () => {
unlisten();
}
}, []);
return null;
}
export default withRouter(ScrollToTop);
We use withRouter
again so that we get the history
prop.
But we call history.listen
instead of checking the value of history
.
We call window.scrollTo(0, 0)
whenever the callback of history.listen
runs.
It returns a function to remove the listen.
So we put that into the function that’s returned in the useEffect
callback.
We pass in an empty array as the 2nd argument of useEffect
to only load the callback when the component mounts.
Then we use it by writing:
<Router>
<>
<ScrollToTop />
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</>
</Router>
Conclusion
We can create our own component to scroll to the top and wrap that around the component that we want to scroll to the top.