I have multiple pages in my react project and, whenever I switch from one page to another the page position starts from the bottom but, I want to stay on top after rendering the page. I'm currently using router v5 and, I can't find any solution for router v5.
I've also tried another version solution but, It didn't work and could you please help me to solve this problem.
These are some of the examples I've tried so far but, not single ones have worked.
<Router onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}>
...
</Router>
function handleUpdate() {
let {
action
} = this.state.location;
if (action === 'PUSH') {
window.scrollTo(0, 0);
}
}
...
<Router
onUpdate={handleUpdate}
/>
I have multiple pages in my react project and, whenever I switch from one page to another the page position starts from the bottom but, I want to stay on top after rendering the page. I'm currently using router v5 and, I can't find any solution for router v5.
I've also tried another version solution but, It didn't work and could you please help me to solve this problem.
These are some of the examples I've tried so far but, not single ones have worked.
<Router onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}>
...
</Router>
function handleUpdate() {
let {
action
} = this.state.location;
if (action === 'PUSH') {
window.scrollTo(0, 0);
}
}
...
<Router
onUpdate={handleUpdate}
/>
Share
Improve this question
asked Oct 28, 2019 at 21:28
zee7zee7
671 silver badge10 bronze badges
3 Answers
Reset to default 12This is the solution I use to solve this problem. Create a new ponent:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
const ScrollToTop = ({ children }) => {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return children || null;
};
export default ScrollToTop;
and wrap your app contents in it INSIDE of the browser router
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import ScrollToTop from './ponents/scroll-to-top/scroll-to-top';
function App() {
return (
<div className="App">
<BrowserRouter>
<ScrollToTop>
<div />
</ScrollToTop>
</BrowserRouter>
</div>
);
}
export default App;
Create the next ponent:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
export default function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return null;
}
Import it in your index.js and use it before Switch ponent, like this:
<ScrollToTop />
<Switch>
...
</Switch>
And it should work.
The above methods of using window.scrollToView(0, 0)
doesn't work for me. Thus, another workaround/solution which works for me is to have a div
at the top with a ref
. The scrollIntoView
method would then be called in the useEffect
hook to scroll the div
into view on render.
import React, { useEffect, useRef } from "react";
const TestComponent = () => {
const topContainer = useRef();
useEffect(() => {
// To make sure page starts from the top
topContainer.current.scrollIntoView({ block: "end", behavior: 'smooth' });
}, []);
return (
<>
<div ref={topContainer} />
<div>Component to be rendered here</div>
</>
);
};
The property behavior: 'smooth'
passed to scrollIntoView
could be omitted too, if you do not want smooth animation of the scroll.