I am trying to accomplish what seems to be default functionality, however with React its not straight forward.
desired behaviour:
- user entered website
- user scrolled down to footer (lets say 700px)
- user clicked link in the footer (that leads to another page)
- clicked page is opened and scroll is on the top (as you would expect)
- user clicked back button
- previous page is opened and scroll is in position where he was when clicking link (as you would expect)
First thing is that when using React and React Router, opened new page is not going to be on the top, it will carry the position from before opening.
I made some research here on stackoverflow, found this topic among many and I solved this part by detecting path change and casting window.scrollTo(0, 0). This is working properly, however when user does click back button, previous page is also going to be opened with scroll on the top, while it should actually be where he left it.
So either this solution is incomplete and something is missing or its just bad solution altogether and should'nt be used or advertised as solution for this problem.
Relevant code:
// index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("index")
);
// App.js
import React, { Component } from "react";
import { BrowserRouter as Router } from "react-router-dom";
import ScrollTop from "./ScrollTop";
class App extends Component {
render() {
return (
<div className="app">
<Router>
<ScrollTop />
...
</Router>
</div>
);
}
}
export default App;
//ScrollTop.js
import React, { useEffect, useState } from "react";
import { Switch, useLocation } from "react-router-dom";
const ScrollTop = () => {
const [prevLoc, setPrevLoc] = useState("");
const location = useLocation();
useEffect(() => {
setPrevLoc(location.pathname);
if (prevLoc !== "" && prevLoc !== location.pathname) {
window.scrollTo(0, 0);
}
}, [location]);
return null;
};
export default ScrollTop;
// Footer.jsx
import React, { Component } from "react";
import { Link } from "react-router-dom";
class Footer extends Component {
render() {
return (
<div className="footer">
<div className="links">
<Link className="link" to="/about">
About
</Link>
</div>
</div>
);
}
}
export default Footer;
Is there a way to achieve desired behaviour and if so how this can be done?