How to Scroll to Top on Route Change with React Router Dom V6

React Router Scroll to Top on V6

As others have pointed out, you are wrapping your Routes component with the ScrollToTop component, but instead of editing it to render its implicit children prop I suggest converting it to a React hook, especially considering since it doesn't actually render anything, you want it to run as a side-effect of navigation.

function useScrollToTop() {
const { pathname } = useLocation();

useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
}

...

function App() {
useScrollToTop();
return (
<div className="App">
<div className="app-body">
<NavBar />
<Routes>
<Route path="/portfolio" element={<Main />} />
<Route path="/portfolio/projects" element={<Projects />} />
</Routes>
</div>
</div>
);
}

This necessarily requires you to lift the Router higher in the ReactTree to wrap the App component so it has a routing context to use for the useScrollToTop hook.

const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<Router>
<App />
</Router>
</StrictMode>,
rootElement
);

How to scroll to the top of the page after a route change, but retain the scroll position when going back?

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

React Router scroll page to the top after transition

Can you try the below

 <BrowserRouter >        
<Layout>
<ScrollToTop />
<Switch>
<Route path="/" exact component={MainPageConfig} />
</Switch>
</Layout>
</BrowserRouter>

React Router v6 - preserve scroll position

Create a component to manage the feed's state, e.g. stateSaver.js:

const state = {}

export const saveState = (component, object) => {

state[component] = object

}

export const getState = (component) => {

return state[component]

}

Then, within your feed.js, retreive the scroll position and use a listener to update it:

import { getState, saveState } from './stateSaver';

useEffect(() => {

if(getState('Feed')){

let { scrollY } = getState('Feed')

window.scrollTo(0, scrollY), 200)

}

}, [])

useEffect(() => {

const save = () => {

saveState('Feed', { scrollY: window.pageYOffset })

}

save()

document.addEventListener('scroll', save)

return () => document.removeEventListener('scroll', save)

}, [])

The solution works assuming that you are working with a single web application.



Related Topics



Leave a reply



Submit