Skip to content
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

Doesn't scroll on reload / refresh #13

Open
cjke opened this issue Jan 19, 2018 · 20 comments
Open

Doesn't scroll on reload / refresh #13

cjke opened this issue Jan 19, 2018 · 20 comments

Comments

@cjke
Copy link

cjke commented Jan 19, 2018

Note This may be out of scope for this package.

Thanks for this package, I have been following this issue for quite a while.

The link works perfectly, however if a reload / refresh occurs, the page no longer scrolls down into position.

@rafgraph
Copy link
Owner

Hi, I'm not able to reproduce this issue. When I go to http://react-router-hash-link.rafrex.com/bar#section-two and refresh in Chrome/Safari/Firefox is scrolls properly (the browser is handling the scroll in this case).

Do you have a failing example I can look at?

@cjke
Copy link
Author

cjke commented Jan 19, 2018 via email

@cjke
Copy link
Author

cjke commented Jan 19, 2018

Sorry my bad, it is working!

Cheers

@cjke cjke closed this as completed Jan 19, 2018
@Ninjami-Juho
Copy link

@cjke How did you get it to work? Having the same issue.

@cjke
Copy link
Author

cjke commented Feb 7, 2018

Well it's strange - for the longest time it wasn't (I swear it wasn't, as I have been looking for solutions from the start of one particular project which required it).

Of recent it just started working. No rhyme, no reason. I don't know if there was a React update, a React Router update, or a Chrome update.

All I can say, is do a hard refresh and start from the top.

@happypeter
Copy link

scroll works for me.

@yantakus
Copy link

In my case content is fetched from API, so when the app loads, content is not there yet and the page remains at the top. Any ideas on how to get it working?

@yamsellem
Copy link

@yantakus you can use this stackoverflow answer to scroll to a given element. Once your fetch is done, for example, you can then force a scroll to a given component (with window.scrollTo(0, this.ref.offsetTop)).

Yes, the solution is not linked to react-router-hash-link, but it's totally compatible. HashLinkwill scroll to a hash, and this technique will scroll on refresh after any async event.

@desmap
Copy link

desmap commented Apr 11, 2019

@RAFREX, I face this issue as well:

If you go to https://7y6r6x2yr0.codesandbox.io/you#go-here from an external source or refresh/reload or enter it manually and press Enter, Chrome does not go to the <div id='go-here'> but stays at the top. Or did I miss anything?

The respective code sandbox:
Edit 7y6r6x2yr0

/cc @cjke

@zcmgyu
Copy link

zcmgyu commented Sep 19, 2019

Same here.

@rafgraph
Copy link
Owner

On a fresh page load the browser handles scrolling to the id that matches the hash in the url. The issue happens when there is a delay in the creation of the element with the id resulting in it not being on the page when the browser tries to scroll to it. Codesandbox has a fair amount of code that runs before loading the app resulting in the above failing example. Note that the example site, http://react-router-hash-link.rafrex.com/baz#section-three, doesn't suffer from this issue.

I have an idea of how to add initial page load scrolling to react-router-hash-link but want this react router issue to be fixed first.

In the mean time you can you can add initial load scrolling to your App's cdm

class App extends React.Component {
  componentDidMount() {
    if (window.location.hash) {
      const id = window.location.hash.replace("#", "");
      const element = document.getElementById(id);
      element.scrollIntoView();
    }
  }
...

You can see this working in codesandbox https://codesandbox.io/s/nifty-varahamihira-dj5qb

@rafgraph rafgraph reopened this Sep 19, 2019
@zcmgyu
Copy link

zcmgyu commented Sep 27, 2019

Thank @RAFREX
I've made customHook for this one.
In case of using lazy and Suspense, let's call useScrollToHash inside imported component.

import { useEffect } from 'react';

export default function useScrollToHash() {
  useEffect(() => {
    const { hash } = window.location;
    if (hash) {
      const id = hash.replace('#', '');
      const element = document.getElementById(id);
      if (element) element.scrollIntoView({ block: 'start', behavior: 'smooth' });
    }
  }, []);
}

@dejanstrancar
Copy link

dejanstrancar commented Dec 19, 2019

@zcmgyu thanks!

your custom Hook did help but i needed to did slight modification, any idea why?
BTW. i have this problem only in Safari.

import { useEffect } from 'react'

export default function useScrollToHash() {
  useEffect(() => {
    //TODO: setTimeout with 0 made it work in Safari - i dont know why
    setTimeout(() => {
      const { hash } = window.location
      if (hash) {
        const id = hash.replace('#', '')
        const element = document.getElementById(id)
        if (element) {
          element.scrollIntoView({ block: 'start', behavior: 'instant' })
          window.scrollBy(0, -55)
        }
      }
    }, 0)
  }, [])
}

@Yaolegol
Copy link

Yaolegol commented Nov 13, 2020

In my case solution is wrap scrollIntoView in setTimeout with delay 100

if (element) {
    setTimeout(() => {
        element.scrollIntoView();
    }, 100);
}

@madnight
Copy link

There is another trick that you can try, but it only works in cases where you exactly know the size of your async result beforehand. For example lets say you have a website with an async search result of 100 Lines (+ maybe a pagination). Then you could prefill the 100 lines synchronously with dummy lines/anchors (empty string), just so that the native scroll anchor mechanism works. Then as soon as your promise gets resolved the real data is filled in and you are already in the correct scroll position.

@imabp
Copy link

imabp commented Jan 22, 2021

Note This may be out of scope for this package.

Thanks for this package, I have been following this issue for quite a while.

The link works perfectly, however if a reload / refresh occurs, the page no longer scrolls down into position.

@cjke you may use this for reference.
https://reactrouter.com/web/guides/scroll-restoration/scroll-to-top

@Jackbaude
Copy link

Jackbaude commented Jan 28, 2021

@zcmgyu thanks!

your custom Hook did help but i needed to did slight modification, any idea why?
BTW. i have this problem only in Safari.

import { useEffect } from 'react'

export default function useScrollToHash() {
  useEffect(() => {
    //TODO: setTimeout with 0 made it work in Safari - i dont know why
    setTimeout(() => {
      const { hash } = window.location
      if (hash) {
        const id = hash.replace('#', '')
        const element = document.getElementById(id)
        if (element) {
          element.scrollIntoView({ block: 'start', behavior: 'instant' })
          window.scrollBy(0, -55)
        }
      }
    }, 0)
  }, [])
}

Yes this is exactly what I needed. Although I needed to remove the last window.scrollBy and it worked!

Edit: I guess all credit actually goes to @zcmgyu

@douglasrcjames
Copy link

How is this implemented into a class component?

@rafgraph
Copy link
Owner

@douglasrcjames see #13 (comment)

@douglasrcjames
Copy link

@rafgraph thanks but I think I was trying to force fit this issue to fit my problem, I will ask another issue to answer my question

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests