Reputation: 1875
I am trying to fix the scrolling issue in React wherein when I was to scroll down to a certain point on the page, and then navigates to another page, that page will begin at the same scroll point as the previous page.
Here's what I tried:
import { useLocation } from 'react-router'
const ScrollToTop: React.FC = () => {
const { pathname } = useLocation()
React.useEffect(() => {
console.log('im scrolling')
window.scrollTo(0, 0)
}, [pathname])
return null
}
export default ScrollToTop
And then imports it like this:
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import ScrollToTop from './components/base/ScrollToTop'
import Apps from './App'
ReactDOM.render(
<BrowserRouter>
<ScrollToTop />
<Apps />
</BrowserRouter>,
document.getElementById('root'),
)
Im scrolling is printing in the console but the window.scrollTo is not working.
I also tried the useLayoutEffect, but the same result still not scrolling.
Upvotes: 7
Views: 8695
Reputation: 1099
I ended up with this hacky solution that works with react-router-dom v6
:
ScrollToTopOnMout.tsx
import { FC, ReactNode, useLayoutEffect } from 'react';
import { useLocation } from 'react-router-dom';
const ScrollToTop: FC<{ children: ReactNode }> = ({ children }) => {
const { pathname } = useLocation();
useLayoutEffect(() => {
window.scrollTo(0, 0);
document.getElementById('full-content')?.scrollTo(0, 0);
}, [pathname]);
return <>{children}</>;
};
export default ScrollToTop;
index.tsx
<BrowserRouter>
<ScrollToTop>
<App />
</ScrollToTop>
</BrowserRouter>
App.tsx
<div id="full-content">
.....
.....
<Routes>
.....
.....
.....
</Routes>
</div>
Upvotes: 1
Reputation: 1875
For those asking how I targeted the parent container. Here's what worked for me. (probably not a clean one but it works)
import React from 'react'
import { useLocation } from 'react-router'
const ScrollToTop: React.FC = () => {
const { pathname } = useLocation()
React.useEffect(() => {
const el = document.getElementById('container-main') // id of the parent
el.scrollTo(0, 0)
}, [pathname])
return null
}
export default ScrollToTop
And use it like this
<div id="container-main">
<ScrollToTop />
....
</div>
Upvotes: 0
Reputation: 949
I had this same issue with react-router v6 and using the following instead of window.scrollTo(0, 0) worked for me:
useEffect(() => {
document.body.scrollTo(0, 0);
});
Upvotes: 3
Reputation: 3914
Try grabbing document.documentElement
or another specific element instead of window
.
const location = useLocation();
useLayoutEffect(() => {
document.documentElement.scrollTo(0, 0);
}, [location.pathname]);
Related: react-router scroll to top on every transition
Upvotes: 4