question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

shouldUpdateScroll returning Array not working

See original GitHub issue

Description

In the documentation of shouldUpdateScroll it says that:

Should return either an [x, y] Array of coordinates to scroll to, a string of the id or name of an element to scroll to, false to not update the scroll position, or true for the default behavior.

However, returning an array won’t actually work.

Steps to reproduce

I’ve dug into this for a while and I think (probably, since I’m not very familiar to gatsby) I’ve found the actual cause of the problem. Instead, I’ll simply write down what I’ve found during my analysis. If I was wrong, please point me out.

It all started in root.js

https://github.com/gatsbyjs/gatsby/blob/205847b833c5f7783182ea54a3ddd72f6369ee47/packages/gatsby/cache-dir/root.js#L68-L72

It imports shouldUpdateScroll from navigate.js:

https://github.com/gatsbyjs/gatsby/blob/83926c8ff1df55898ffdeb49183163b5f0bc4270/packages/gatsby/cache-dir/navigation.js#L125-L151

It uses apiRunner, which I suppose (due to the lack of knowledge about the internals) should collect shouldUpdateScroll from all plugins, which, in my case, is only provided by gatsby-remark-autolink-headers.

This function is then passed to ScrollHandler, which uses it in its shouldUpdateScroll instance method:

https://github.com/gatsbyjs/gatsby/blob/40724e87dc36d9a22e3dd9095b8f2c872a5bd299/packages/gatsby-react-router-scroll/src/scroll-handler.tsx#L91-L102

So who uses this.shouldUpdateScroll? The answer is windowScroll and scrollToHash:

https://github.com/gatsbyjs/gatsby/blob/40724e87dc36d9a22e3dd9095b8f2c872a5bd299/packages/gatsby-react-router-scroll/src/scroll-handler.tsx#L71-L89

The problem is that both method didn’t actually use the return value of shouldUpdateScroll, so if the return value is an array, it is simply ignored.

Relationship to other issues

My motive is that we wanted to click on markdown headers and update the hash, and found out that sometimes, clicking on a header makes it jump to the screen top, and sometimes it doesn’t. That is similar to the behaviour described in #25778.

First I thought that maybe gatsby-remark-autolink-headers got something wrong, but it didn’t. The actual cause is, again, rooted within gatsby-react-router-scroll. So in componentDidUpdate:

https://github.com/gatsbyjs/gatsby/blob/40724e87dc36d9a22e3dd9095b8f2c872a5bd299/packages/gatsby-react-router-scroll/src/scroll-handler.tsx#L56-L69

This is supposed to be called when the path changes, and tries to restore the user’s last scroll position on the new page, however it also gets called when the page hash updates, when it still tries to do the same thing.

That said, clicking on an in-page anchor does two things:

  1. Updates page hash, emitting a hashchange event.
  2. Scrolls (actually jumps) to the referenced element, emitting a scroll event.

If the former comes first, the router calls componentDidUpdate, which uses the last scroll position and calls window.scroll, which somehow ‘cancels out’ the latter one (I presume that’s because the browser sends only one scroll event per frame), so in the end, nothing changes.

If the latter comes first, the page first scrolls, updating last scroll position, and componentDidUpdate calls window.scroll with the new scroll position, so the page jumps to the desired position.

That might solve the myth of #25778, although in my case another weird thing is that my browser (Chrome 84.0.4147.89) seems to stick to an order for an uncertain amount of time, and then switches to another.

The simple solution is to return false from shouldUpdateScroll when nothing but the hash changes, and let the browser do everything for you, but I’m thinking about preventing the auto-jump behavior of the browser and passing control to shouldUpdateScroll, however had yet no luck of finding a solution.

Hope that’d be of help.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:5

github_iconTop GitHub Comments

2reactions
schmallisocommented, Dec 14, 2020

We’re still seeing this issue! We’d hoped that https://github.com/gatsbyjs/gatsby/pull/28555 would address it, but sadly we’re still having problems with our scroll situation.

0reactions
github-actions[bot]commented, Feb 13, 2021

Hey again!

It’s been 60 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to comment on this issue or create a new one if you need anything else. As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community! 💪💜

Read more comments on GitHub >

github_iconTop Results From Across the Web

Gatsby Browser APIs
Should return either an [x, y] Array of coordinates to scroll to, a string of the id or name of an element to...
Read more >
javascript return array not working - Stack Overflow
The real problem is that the call to the calendar API might take an arbitrary amount of time (it's asynchronous), so you can't...
Read more >
How to fix Gatsby JS Link component retaining scroll position ...
I have a feeling it's something to do with my styles, as I started a new project and the Gatsby-cli had no issues....
Read more >
How to Return an Array in a C++ Function - DigitalOcean
Typically, returning a whole array to a function call is not possible. We could only do it using pointers. Moreover, declaring a function...
Read more >
JavaScript Array.from() Method
In this tutorial, you will learn about the Array.from() method to create a new array from an array-like or iterable object.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found