Monday, 11 November 2019

How to implement scroll restoration for React Router SPA

I'm building a React single-page application, and I've noticed the scroll restoration does not appear to work as expected in Chrome.

On the react-router-dom github repo, they have a page that says that browsers are starting to natively handle scrolling for single page apps, and the behavior would be similar to that of a traditional non-SPA web page, if history.scrollRestoration is set to auto.

The behavior I need is indicated on that page:

  1. Scrolling up on navigation so you don't start a new screen scrolled to the bottom.
  2. Restoring scroll positions of the window and overflow elements on "back" and "forward" clicks (but not Link clicks!)

Here's a link to Chrome's spec on the issue.

What I'm observing in Chrome Version 78.0.3904.97 (Official Build) (64-bit) for OS X, is what appears to be what I'd expect from the history.scrollRestoration manual setting. That is, when I'm scrolled half way down a page, and I click a link, the next page is scrolled halfway down the page, to the same point as the previous page.

I thought maybe it's set to manual somewhere that I'm not seeing, so I checked the history.scrollRestoration at the top of the index.html entry point, and again after a several-second timeout, and the setting starts, and remains auto, the default.

One point of significance here is this from @TrevorRobinson's answer "the browser's automatic attempts at scroll restoration... ...mostly don't work for single-page apps..." Ok... I found consistent support for history.scrollRestoration, but apparently browsers are crappy at actually DOING the scroll restoration. Then that should be noted here, which would have saved me time today.

Then I look up ways to do this manually, and I'm not clear of the way forward. react-router-scroll says it's not compatible with React Router v4, but doesn't mention v5, which is current as of this question. So should I assume v5 is also not compatible?

So I look further for a way forward, and found this SO answer about how to handle scroll restoration with React Router v4... So should I assume that will work with React Router v5? Update: It does not appear to work for me in v5. I tried several configurations. I also could not get it completely working with React Router v4. I knew it came alive at least, as it was it scrolls to top on a new page, but restoration in the history does not occur.

I did also get react-router-scroll-memory working, but it does not have options for disabling scrolling on designated routes, like what would be needed for tabs or a carousel. I have a carousel. But I might just hack it to make it work for me tonight.

I considered using oaf-react-router, but it says nothing in the documentation about disabling scroll restoration for certain routes.

Is there something I've overlooked? What is the standard for dealing with this issue, because I can't be the only one who need this feature. It seems like I'm doing something edgy and experimental, but I just need my site to scroll like a normal site.



from How to implement scroll restoration for React Router SPA

No comments:

Post a Comment