-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scroll management #3950
Comments
I have a POC on my machine, but it requires #3956 to be fixed before it works. |
@mjackson it is fixed! just not released yet. |
@ryanflorence Any updates on this? Scroll management would be good to have in a router :) |
ScrollManagement on v4 still open or fixed? I to would my page to show the same after router.goBack() |
As a temporary solution this SO Question + Accepted answer have worked for me: http://stackoverflow.com/questions/40217585/in-react-router-v4-how-does-one-link-to-a-fragment-identifier |
@mjackson Are we deferring to the browsers on this or putting something together (or updating your POC)? |
I'll see if I can push an updated POC soon. |
Party pooper here. In case of next POC will take next several months, maybe this could help meanwhile: https://github.com/4Catalyzer/found-scroll |
😂 @steida, you're such a helpful ray of sunshine. thank you! |
Whoa, just looked at found and ... found some code that is eerily similar to my code. Creepy. |
OK, I'm going to try and find an elegant solution to this problem this week for (at least the DOM bindings in) v4. Up to this point I've focused all my attention on making sure we had a good core, and now that we're shipping v4 betas every few days I think we're there. If you're interested in trying to scratch your own itch and solve this problem for your app, but you've been hesitant because v4 was too unstable, you should feel free to give it a shot now too. For folks who are interested, we've got quite a backstory that you can follow right here in this repo. Here are a few links that should help you get a feel for research that has already been done in previous versions:
And for everyone who thinks "oh my gosh I can't believe they don't have an answer for this yet" I refer you to #707 (comment):
If you're in the middle of a project with complex scroll management requirements right now, I'd love to hear about it and/or see your proposed solutions. The v4 API is much more modular than past versions, so it should be a lot easier than it used to be to get in and alter how the router works simply by inserting components into the tree. I've got a POC that currently preserves the scroll position on /cc @gaearon @ryanflorence @taurose because reading through those old issues made me remember those days when we were just getting started on this project very fondly 💕 |
We decided to adopt react-router 4 around the second alpha and went to production at around alpha-5 The key stakeholders of our site were happy for us to land with a solution that simply scrolled to top on a forward navigation, which was very simple to implement with the v4 API. 👍 We are currently looking at updating to the beta and as part of that we will be looking at implementing the following scroll behaviors. Upon navigating to a content page, scrolling to the content in the page (skipping header) Ensuring on backwards navigation, with fresh state being used to render, the user is ether;
The v4 api has been a pleasure to work with so far. |
Related: scroll restoration is coming to browsers through a proposed addition to the HTML5 history API. Something to keep in mind. |
Poor man's scroll restoration: On lwjgl.org we code-split (webpack 2) each route so we have to wrap each route component with https://github.com/LWJGL/lwjgl3-www/blob/master/client/routes/asyncRoute.js It was natural to put the scroll restoration code there. Our approach is very simple and it uses the generated location.key to remember the scroll position. If we get a POP action we restore the previous scroll position otherwise we scroll to top. It works really well for a simple content website. Caveats:
A cleaned-up version of the HOC can be found here: https://gist.github.com/apostolos/7001146c5437368eef2d281f9ecfb3c8 |
We're in the final week before launching a beta of our next app that relies heavily on RR4 (we've been confident enough in the RRv4 changes that warranted using a alpha/beta version in our app). As mentioned above, the accepted solution in this question http://stackoverflow.com/questions/40217585/in-react-router-v4-how-does-one-link-to-a-fragment-identifier has been working perfectly for us - we've had no issues with it so far, and works well. I understand its only a piece of the pie, as it addresses only the jump to a fragment identifier part of the problem, but is still useful regardless. |
I wanted to jot down some thoughts on scroll management. I've implemented it several times as the router (and its beta releases) have changed over the last couple of years. I've implemented it as components outside of the router, inside of the router, inside of the Do we need it?I'm not sure we need to do anything about it (😂). Browsers are starting to handle scroll restoration with Scroll Restoration Spec: https://majido.github.io/scroll-restoration-proposal/history-based-api.html#web-idl Most of the time all you need is to "scroll to the top" because you have a long content page, that when navigated to, stays scrolled down. That's easy, this will scroll up your entire app on every navigation: class ScrollToTop extends Component {
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
window.scrollTo(0, 0)
}
}
render() {
return null
}
}
const ScrollToTopOnNav = () => (
<Route component={ScrollToTop}/>
)
// Then render it at the top of your app
const App = () => (
<div>
<ScrollToTopOnNav/>
</div>
) Or you could do it in just the components that need it when they mount: class ScrollToTopOnMount extends Component {
componentDidMount(prevProps) {
window.scrollTo(0, 0)
}
render() {
return null
}
}
class LongContent extends Component {
render() {
<div>
<ScrollToTopOnMount/>
<h1>Here is my long content page</h1>
</div>
}
}
// somewhere else
<Route path="/long-content" component={LongContent}/> So what about a more robust generic solution? We're talking about two things:
For a generic API I was headed toward this: <Router>
<ScrollRestoration>
<div>
<h1>App</h1>
<RestoredScroll id="bunny">
<div style={{ height: '200px', overflow: 'auto' }}>
I will overflow
</div>
</RestoredScroll>
</div>
</ScrollRestoration>
</Router> First, What got tricky for me was defining an "opt-out" API for when I didn't want the window to scroll to be managed. For example, if you have some tab navigation floating inside the content of your page you probably don't want to scroll to the top (the tabs might be scrolled out of view!). When I learned that chrome manages scroll position for us now, and realized that different apps are going to have different scrolling needs, I kind of lost the belief that we needed to provide something--especially when usually people just want to scroll to the top (which you saw is trivial to add to your app on your own). So, yeah ... I'm not sure we need it but that API I just showed above would be pretty straightforward to implement (assuming you have a good wrapper around session storage!). I no longer feel strongly enough to do the work myself (plenty other things for me to work on!) but I'd love to help anybody who feels inclined. A solid solution would even live in this monorepo and be an official package. Hit me up if you get started on it :) |
@ryanflorence Maybe we just add |
I second @mjackson's opinion. |
This would make a great PR for someone who wants to go for it. Removing the 4.0.0 milestone because I don't consider this blocking for v4. |
This is what we've been using for a few weeks now: https://gist.github.com/spicydonuts/d1ca3d78b9448004455562af1f04f81e It's not real pretty but it behaves close to how you'd expect the browser to, all contained in one component. It also means other components which get |
Alright, doc is written so I can close this now :) |
The docs look really awesome. Can I confirm that scrolling to a fragment identifier is outside of scope of the docs, the library and this issue? |
For basic scroll to Live example: http://react-router-hash-link.rafrex.com When you click on a link created with $ npm install --save react-router-hash-link // In YourComponent.js
...
import { HashLink as Link } from 'react-router-hash-link';
...
// Use it just like a RRv4 link:
<Link to="/some/path#with-hash-fragment">Link to Hash Fragment</Link> |
maybe it varies by browser, but with |
@ryanflorence, it doesn't seem to work for me in chrome/safari/firefox. I created a branch of the example site using Browser Router and the Link component to test it out. Can you give it a try and let me know if you get different results. Thanks. $ git clone -b browser-router-link https://github.com/rafrex/react-router-hash-link.git
$ npm install
$ npm start The site will be available on port |
In case anyone finds it useful, I created a React scroll management library to address the various issues mentioned here:
Please give it a try and submit issues/PRs if you find any issues: https://github.com/trevorr/react-scroll-manager It targets React 16 and supports React Router 4, though it's actually agnostic to the router (except that it indirectly uses the |
Loving the v4 API currently! Wanted to start a thread on this so the community can stay updated. From the FAQ:
Whose working on this, and whats the ETA for this? Will it still be provided by the
react-router-scroll
library?The text was updated successfully, but these errors were encountered: