23

Where do I have to put the window.scrollTo(0,0) call in a react component?

I tried to put it directly into render and also tried componentDidUpdate (to wait till everything is rendered), but somehow the scrollbars always stay at the same position.

-- Edit --

The problem was CSS height/overflow of the window and body.

See: https://stackoverflow.com/a/18573599/1016383

1
  • You should put it in componentDidMount Commented Jun 30, 2015 at 10:21

10 Answers 10

30

window.scrollTo only works when the scroll behavior is set on html.
If scroll is set on body then document.querySelector("body").scrollTo(0,0)

If you have set overflow: scroll on some container inside of the DOM, then that need to be accessed. Assign an id to that. For example I have below div container for which I have set overflow: scroll.

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="root">
      <div id="scroller">
        <!-- other content -->
      </div>
    </div>    
  </body>
</html>

Then for scrolling behavior, you need to query the scroller.

const scrollToTop = () => {
  document.getElementById("scroller").scroll(0,0)
}

<button onClick={scrollToTop}>Scroll to Top</button>

This would work perfectly.

Sign up to request clarification or add additional context in comments.

Comments

14

Well, window.scrollTo(0,0) would always stick to the top of the page.

You are correct in saying this code should live in the componentDidMount function, but you need to tell it where to scroll. I would locate the id of the element you want to scroll to and obtain it's y coordinates, than you enter that into the window.scrollTo and it should work. You may need to get the height of the component and add that to this dymamic value you obtained.

5 Comments

So even if it's a window method and I use 0,0 it won't scroll to the top of the page and I need actual coordinates of an element on the page?
well no actually, wherever that is called it should scroll to the top of the page. So are you sure this is being called? have you tried an alert on your componentDidMount function? I thought you were trying to scroll to where your component was located.
it gets called, it just doesn't do anything.
@ChrisHawkes why must it live in componentDidMount, what if you wanted only to scroll after a function has been called?
@TheWalrus I think K. means if you want to scroll once after the componentDidMount, but if you want to scroll after a specific event effectively I do think it is better to include it in the relevant place of your code's flow
11

I tried everything I found on this issue with React, the only one that worked for me was with 'scrollIntoView' seen in this below code;

document.getElementById('element')?.scrollIntoView({ behavior: 'smooth' });

Comments

9

Another scenario could be that the application is not set up to have the window handle its scrolling. It could be a 'widget' where the window is static and an inner element handles the scrolling. A good way to test this is to enter window.scrollTo(0,0) right there in your console. If your window doesn't pop to the top there, you'll need to seek another solution. Likely you'll need to get the element that is doing the actual scrolling and handle it with Element.scrollTo(0,0)

1 Comment

I think I have the issue you mentioned. I'm working on an open-source project and window.scrollTo() does not work in that app. I had to use document.querySelector('body').scrollTo(0,0) to make it work. This is weird.
8

Like @Reed Black mentioned in his answer, the problem might be window.scrollTo(0,0) does not work for the particular app.

I encountered this problem in an open-source project. The app won't scroll using window.scrollTo(0,0) like other websites would.

I had to use document.querySelector('body').scrollTo(0,0) to make it work.

Comments

1

Somehow the querySelector didn't work for me. But the getElementById did. Here's an example for trigger the 'scroll back to top' from another component.

export default function View() {
  return <div id='view'> A </div>
}

export default function Button() {
  const backToTop = () => {
    document.getElementById('view').scrollTo({ top: 0, behavior: 
      'smooth' 
    })
  }

  return <button onClick={backToTop}>Back to Top</button>
}

export default function App() {
  return (
    <ComponentA/>
    <Button/>
  )
}

Comments

0

Well, it is React and direct DOM manipulations are unwelcome. One can solve this with ref, however it may seem a little bit cumbersome. Namely, one must have an element like Header on the page visible top and agree that scrolling to have this element in view is what one wants.

The simplified example from my page(with TS) is as follows:

const Page = () => {
  const ref: React.Ref<HTMLHeadElement> = React.createRef();
  const goToHeader = () => {
    if (ref.current) {
      ref.current.scrollIntoView({ behavior: "smooth" });
    }
  };
  return (
    <>
      <Header ref={ref} />
      ...any content here... 
      <button onClick={goToHeader}>TEST</button>
    </>
  );
};

Header is:

const Header = forwardRef((props: Props, ref: Ref<HTMLHeadElement>): JSX.Element | null => {
  return (
    <header className="WeatherInformationsPage__header" id="header" ref={ref}>
      ... any actual content goes here ...
    </header>
  );
});

export default Header;


Comments

0

For React, this works perfectly

useEffect(() => {
    window.scroll(0, 0);
}, []);

Comments

0

In React for me the App_container was holding the scrolling functionality. But the className value is automatically generated. I got to it by getting the root and then the first child.

document.getElementById('root')?.children[0]?.scrollTo(0,0)

Comments

0

You can use useEffect for scrolling an element to a certain position when a component mounts or when specific dependencies change. Here's an example of how you can use it to smoothly scroll an element:

import React, { useEffect } from 'react';

const MyComponent = () => {
  useEffect(() => {
    // Assume "video-container" is the ID of the element you want to scroll
    const videoContainer = document.getElementById("video-container");
    
    if (!videoContainer) return; // Make sure the element exists

    // Set a timeout to delay the scrolling slightly for smooth behavior
    setTimeout(() => {
      videoContainer.scrollTo({
        top: 100, // Adjust a value
        behavior: "smooth"     // Smooth scroll
      });
    }, 100); // Adjust timeout as needed for UX

  }, []); // Add dependencies here if the scroll should react to changes

  return <div id="video-container">Your content here</div>;
};

export default MyComponent;

Comments

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.