10

I am creating a component that will hold a dynamic list of elements and for styling reasons, I need to keep the title for each section in a sticky nav menu. As the user scrolls up and down the list of sections I need to apply styling rules and also bring the same section in the menu nav into view so I've tried using scrollIntoView with the menu section ref.

My inner workings and logic seem to work as expected, there is however an issue - unless I inspect or use a refresh on the page, the function for scrollIntoView does not execute on every state change

const scrollTo = (ref) => {
  ref.current.scrollIntoView({ behavior: "smooth", inline: "center" });
};

To keep things short I have added my workings into this codesandbox

Any help would be greatly appreciated as I've run out of ideas.

Thanks

Edit:

The scrolling behaviour seems to work as expected if I remove the "smooth" option in the behavior parameter from the scrollIntoViewOptions options. It does however look jumpy.

const scrollToMenu = (ref) => {
  ref.current.scrollIntoView({ inline: "center", });
};
3
  • Note that it works on firefox Commented Mar 30, 2022 at 20:07
  • Cheers for that... Interested to know how to handle this in order to support the majority of major browsers. Commented Apr 4, 2022 at 14:01
  • I have the same issue on Chrome & Brave only, my scrollIntoView functions don't work AT ALL when I have behavior: smooth on. When I remove the smooth, it works but not a good user experience of course. Did you ever solve this? Commented Jul 20, 2022 at 13:16

2 Answers 2

7

Curiously, scrollIntoView() doesn't work when called synchronously, but in my case, putting it into a setImmediate() worked fine:

const scrollToMenu = (ref) => {
    setImmediate(() => ref.current.scrollIntoView({ inline: "center", }));
};
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for that, I don't understand why this work but it does.
6

In my case setImmediate() was not available but setTimeout() suited my purposes:

const scrollTo = (ref) => {
    setTimeout(() => ref.current.scrollIntoView({ inline: 'center', behavior: 'smooth' }), 777)
}

1 Comment

setting the delay to 0 worked for me. setTimeout(() => ref.current.scrollIntoView({ behavior: 'smooth' }), 0)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.