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
Infinite Rotation Animation Using CSS and JavaScript
JavaScript Image Overlay Over a Specified Div
How to More Accurately Measure Svg Text Height
Semantic-Ui Modal Size Keeps Extending to the Height of a Page
Bootstrap Progress Bar Progression
Indicate That Processor-Heavy Js Function Is Running (Gif Spinners Don't Animate)
Changing Background Color of a Specific Row in Slickgrid
Uncaught Typeerror: Cannot Set Property 'Onclick' of Null
Get Actual Value Specified in CSS Using Jquery
Jquery UI Datepicker: Don't Highlight Today When It Is Also Selected
How to Build SASS/Less/CSS in Webpack Without Requiring Them in My Js
How to Change the Viewport Meta Tag in Mobile Safari on the Fly
How to Get JavaScript Variable Value into CSS
How to Enable the JavaScript Error/Debug Console for Safari Within Android
Adding a Background Video with React
Javascript: Advantages and Disadvantages of Dynamically (On Fly) Creating Style Element