K..
K..

Reputation: 4223

window.scrollTo() in react components?

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

Upvotes: 23

Views: 107821

Answers (10)

matrixb0ss
matrixb0ss

Reputation: 933

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;

Upvotes: 0

zzzzteam
zzzzteam

Reputation: 23

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)

Upvotes: 0

Caleb C. Adainoo
Caleb C. Adainoo

Reputation: 97

For React, this works perfectly

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

Upvotes: 0

Kiszuriwalilibori
Kiszuriwalilibori

Reputation: 329

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;


Upvotes: 0

Ike Anya
Ike Anya

Reputation: 201

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' });

Upvotes: 10

Shin ShiBa
Shin ShiBa

Reputation: 31

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/>
  )
}

Upvotes: 1

The Coder
The Coder

Reputation: 4027

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.

Upvotes: 30

Muchdecal
Muchdecal

Reputation: 177

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.

Upvotes: 8

Reed Black
Reed Black

Reputation: 111

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)

Upvotes: 9

Chris Hawkes
Chris Hawkes

Reputation: 12410

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.

Upvotes: 14

Related Questions