react-firebase-starter icon indicating copy to clipboard operation
react-firebase-starter copied to clipboard

Scroll to top when routes change

Open rigobcastro opened this issue 8 years ago • 4 comments

Explaining how to do it would be very useful and interesting.

Thanks!

rigobcastro avatar Mar 09 '17 02:03 rigobcastro

For example you can see how this stuff is implemented in react-starter-kit/src/client.js

// Switch off the native scroll restoration behavior and handle it manually
// https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration
const scrollPositionsHistory = {};
if (window.history && 'scrollRestoration' in window.history) {
  window.history.scrollRestoration = 'manual';
}

let currentLocation = history.location;
function onLocationChange(location, action) {
  // Remember the latest scroll position for the previous location
  scrollPositionsHistory[currentLocation.key] = {
    scrollX: window.pageXOffset,
    scrollY: window.pageYOffset,
  };
  // Delete stored scroll position for next page if any
  if (action === 'PUSH') {
    delete scrollPositionsHistory[location.key];
  }
  currentLocation = location;

  // render page here and then...

  let scrollX = 0;
  let scrollY = 0;
  const pos = scrollPositionsHistory[location.key];
  if (pos) {
    scrollX = pos.scrollX;
    scrollY = pos.scrollY;
  } else {
    const targetHash = location.hash.substr(1);
    if (targetHash) {
      const target = document.getElementById(targetHash);
      if (target) {
        scrollY = window.pageYOffset + target.getBoundingClientRect().top;
      }
    }
  }

  // Restore the scroll position if it was saved into the state
  // or scroll to the given #hash anchor
  // or scroll to top of the page
  window.scrollTo(scrollX, scrollY);
}

// Handle client-side navigation by using HTML5 History API
// For more information visit https://github.com/mjackson/history#readme
history.listen(onLocationChange);
onLocationChange(currentLocation); // init the app

frenzzy avatar Mar 09 '17 15:03 frenzzy

Ok very thanks but Where in RSB?

rigobcastro avatar Mar 09 '17 18:03 rigobcastro

Couldn't you use simple javascript in componentDidMount to accomplish this?

componentDidMount() {
        window.scrollTo(0, 0);
}

I can think of many cases where you wouldn't by default want to start at the top of a page when a route changes. Why add additional complexity to the framework, when in most cases, one simple line of code should do the trick? Using this method also gives you more flexibility on a per component basis in case you do have special requirements, like implementing anchor locations on a specific page that the component is rendering.

mrgswift avatar Mar 13 '17 17:03 mrgswift

@mrgswift Thanks for your suggestion, in my case when a route changes always appears in the middle of page, I need always that the pages start on the top.

I will try your suggestion.

rigobcastro avatar Mar 13 '17 17:03 rigobcastro