344

I have a problem, which I have no ideas, how to solve. In my react component I display a long list of data and few links at the bottom. After clicking on any of this links I fill in the list with new collection of the links and need to scroll to the top.

The problem is - how to scroll to the top after new collection is rendered?

'use strict';

// url of this component is #/:checklistId/:sectionId

var React = require('react'),
  Router = require('react-router'),
  sectionStore = require('./../stores/checklist-section-store');


function updateStateFromProps() {
  var self = this;
  sectionStore.getChecklistSectionContent({
    checklistId: this.getParams().checklistId,
    sectionId: this.getParams().sectionId
  }).then(function (section) {
    self.setState({
      section,
      componentReady: true
    });
  });

    this.setState({componentReady: false});
 }

var Checklist = React.createClass({
  mixins: [Router.State],

  componentWillMount: function () {
    updateStateFromProps.call(this);
  },

  componentWillReceiveProps(){
    updateStateFromProps.call(this);
   },

render: function () {
  if (this.state.componentReady) {
    return(
      <section className='checklist-section'>
        <header className='section-header'>{ this.state.section.name }   </header>
        <Steps steps={ this.state.section.steps }/>
        <a href=`#/${this.getParams().checklistId}/${this.state.section.nextSection.Id}`>
          Next Section
        </a>
      </section>
    );
    } else {...}
  }
});

module.exports = Checklist;
Andrew Kovalenko
  • 6,441
  • 2
  • 29
  • 43

39 Answers39

600

Finally.. I used:

componentDidMount() {
  window.scrollTo(0, 0)
}

EDIT: React v16.8+

useEffect(() => {
  window.scrollTo(0, 0)
}, [])
sledgeweight
  • 7,685
  • 5
  • 31
  • 45
  • 3
    This is only solution that worked for me. Also tried: ReactDOM.findDOMNode(this).scrollTop = 0 and componentDidMount() { this._div.scrollTop = 0 } render() { return
    this._div = ref} /> }
    – Michael Bushe Oct 09 '16 at 05:47
  • According to W3Schools, this solution is currently supported by all browsers. Also the ReactDOM library is being deprecated in future versions of React. – BishopZ Jan 24 '17 at 22:21
  • 2
    @Tomasz - I found i still had this issues sometimes when I had certain divs set to height or min-height: 100%. I had to remove and either wrap it in a parent or move further into the tree where it could still scroll – sledgeweight Feb 28 '17 at 21:36
  • With `window.scrollTo(0, 0)` its not a smooth transition. Is there a way to achieve that? – Hozefa Mar 01 '17 at 00:04
  • 3
    This worked for me but not under componentDidMount, since CDM may not be fired when the state change results in a re-rendering of the page. So put this call -- window.scrollTo(0, 0); -- wherever it is you change the state. – Puneet Lamba Jun 25 '17 at 01:56
  • Nice one, helped me out in first go. – Siddharth Sachdeva Dec 25 '17 at 08:15
  • Thanks, this is a very pragmatic solution for most situations that don't involve `react-router` – James Dec 11 '18 at 21:03
  • You should also reset keyboard focus at the same time as scrolling to top. I wrote a thing to take care of it: https://github.com/oaf-project/oaf-react-router – danielnixon May 09 '19 at 05:03
  • 10
    For those using hooks, the following code will work. `React.useEffect(() => { window.scrollTo(0, 0); }, []);` Note, you can also import useEffect directly: `import { useEffect } from 'react'` – Powderham Jul 19 '19 at 10:54
  • I've been trying to do this with useref, finally you saved my time, thanks – Chukwuemeka Maduekwe Jul 02 '20 at 13:49
  • you deserve more votes... I've spent so much time search on other pages... – cs.yan Aug 20 '20 at 21:27
  • I had to add the `useLocation()` hook from `react-router-dom` to get this to work for me in case anyone else has any issues: https://reactrouter.com/web/guides/scroll-restoration Full code: `import { useEffect } from "react"; import { useLocation } from "react-router-dom"; export default function ScrollToTop() { const { pathname } = useLocation(); useEffect(() => { window.scrollTo(0, 0); }, [pathname]); return null; }` – David Yeiser Oct 21 '20 at 12:02
  • I had to leave away the second argument `[]` of `useEffect`, since I needed to scroll to the top on every re-rendering. – Carsten Führmann Nov 22 '20 at 17:41
  • i added an answer to useEffect but making it work when a state variable changes: https://stackoverflow.com/a/65832313/652318 – Andy Jan 21 '21 at 17:06
  • I can recommend adding additional options to have a smooth transition `window.scrollTo({top: 0, left: 0, behavior: 'smooth'});` (credit to https://bobbyhadz.com/blog/react-scroll-to-top) – Michael Oct 17 '22 at 21:16
98

Since the original solution was provided for very early version of react, here is an update:

constructor(props) {
    super(props)
    this.myRef = React.createRef()   // Create a ref object 
}

componentDidMount() {
  this.myRef.current.scrollTo(0, 0);
}

render() {
    return <div ref={this.myRef}></div> 
}   // attach the ref property to a dom element
Andrew Kovalenko
  • 6,441
  • 2
  • 29
  • 43
  • 1
    this.getDOMNode === undefined – Dave Lunny Apr 26 '16 at 20:21
  • 1
    @DaveLunny you may be on react15? try importing ReactDOM and doing `ReactDOM.findDOMNode(this).scrollTop = 0` – Marcus Ericsson May 05 '16 at 19:39
  • 12
    `this is undefined in arrow functions` is incorrect. The this keyword is bound to the same context as the enclosing function https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – Joe Delgado Sep 18 '16 at 08:02
  • If possible you should avoid ReactDom.findDOMNode(). Use a ref instead. I posted [a solution using smooth scroll here](https://stackoverflow.com/a/52998588/4699593) – bbrinx Dec 07 '18 at 18:24
  • default.a.createRef is not a function – Anupam Maurya Aug 19 '19 at 11:34
  • This does not appear to be as accurate as scrollIntoView, where the later bring the field in question to the top of the page while the .scrollTo(0,0) only seem to bring it into view but not to the top of the page, about 30% up. Weird! – Thierry Jan 25 '20 at 06:21
  • how does this look like in a functional component ? – Gel Nov 01 '22 at 01:32
60

You could use something like this. ReactDom is for react.14. Just React otherwise.

    componentDidUpdate = () => { ReactDom.findDOMNode(this).scrollIntoView(); }

Update 5/11/2019 for React 16+

  constructor(props) {
    super(props)
    this.childDiv = React.createRef()
  }

  componentDidMount = () => this.handleScroll()

  componentDidUpdate = () => this.handleScroll()

  handleScroll = () => {
    const { index, selected } = this.props
    if (index === selected) {
      setTimeout(() => {
        this.childDiv.current.scrollIntoView({ behavior: 'smooth' })
      }, 500)
    }
  }
mauris
  • 42,982
  • 15
  • 99
  • 131
J. Mark Stevens
  • 4,911
  • 2
  • 13
  • 18
  • Of all the suggestions on this page, this is the only one that works for me. – Josh F Mar 20 '17 at 00:58
  • Note: if componentDidUpdate does not work for you, `componentDidMount` is another alternative. – Alex Fallenstedt Apr 24 '17 at 05:31
  • findDOMNode is an escape hatch used to access the underlying DOM node. In most cases, use of this escape hatch is discouraged because it pierces the component abstraction. It has been deprecated in StrictMode. https://reactjs.org/docs/react-dom.html – Vivek Kumar Nov 06 '19 at 06:51
28

Hook solution:

  • Create a ScrollToTop hook

    import { useEffect } from "react";
    import { withRouter } from "react-router-dom";

    const ScrollToTop = ({ children, location: { pathname } }) => {
      useEffect(() => {
        window.scrollTo({
          top: 0,
          left: 0,
          behavior: "smooth"
        });
      }, [pathname]);

      return children || null;
    };

    export default withRouter(ScrollToTop);

  • Wrap your App with it

    <Router>
        <ScrollToTop>
           <App />
        </ScrollToTop>
    </Router>

Documentation : https://reacttraining.com/react-router/web/guides/scroll-restoration

Quentin C
  • 1,739
  • 14
  • 26
27

In React Routing there is the problem that if we redirect to the new route, then it won't automatically take you to the top of the page.

Even I did have the same issue.

I just added the single line to my component and it worked like butter.

componentDidMount() {
    window.scrollTo(0, 0);
}

Refer: react training

Afaq Ahmed Khan
  • 2,164
  • 2
  • 29
  • 39
Vishal Shetty
  • 1,618
  • 1
  • 27
  • 40
  • is this the recommended way if I use this for my 'jump to top' button? or if there's a 'react' way where we don't use the window object? – Toxnyc Aug 06 '19 at 20:30
  • 1
    Thanks for bringing into the notice, the solution I have given is applicable for a react-router dom version less than v5, I was using v4.2.2 and there when you navigate to another page you weren't taken by default to the top of the page, so we have to manually take the user to the top of the page after navigation, but with v5.0.1 react-router dom stopped shipping the scroll restoration out of the box, because as per their document they say that browsers started supporting this feature by default and with latest version of react-router-dom you will taken to the top of the page after navigation. – Vishal Shetty Aug 07 '19 at 04:03
  • 1
    @Toxnyc so using window object is what Javascript is, If react is on top of Javascript then even if you use any of the React Plugin behind the scenes it will be using Javascript and window object only, as per my knowledge react document is not having anything by which we can get the details of window screen. we have to go with Javascript for making it work. – Vishal Shetty Aug 07 '19 at 04:06
22

For those using hooks, the following code will work.

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

Note, you can also import useEffect directly: import { useEffect } from 'react'

Powderham
  • 1,510
  • 12
  • 14
  • 2
    The `[]` as the second parameter means it will only happen on the first render, have you tried without? – Powderham Aug 14 '19 at 15:26
13

This could, and probably should, be handled using refs:

"... you can use ReactDOM.findDOMNode as an "escape hatch" but we don't recommend it since it breaks encapsulation and in almost every case there's a clearer way to structure your code within the React model."

Example code:

class MyComponent extends React.Component {
    componentDidMount() {
        this._div.scrollTop = 0
    }

    render() {
        return <div ref={(ref) => this._div = ref} />
    }
}
GGAlanSmithee
  • 345
  • 1
  • 5
  • 11
  • This works great. Thanks. To be clear, I put the `
    this._div = ref} />` in the very first `
    ` of my render statement. The rest of my render stays exactly the same.
    – Josh F Jan 11 '17 at 18:42
  • In case you are using Styled components you will need to use "innerRef" instead of "ref". Great solution – furcicm Apr 11 '18 at 19:30
  • Totally works. For what I was working on, I could be even simpler with `
    ` and then `this.refs.main.scrollTop=0`
    – chuckfactory Aug 14 '18 at 13:14
  • 2
    @chuckfactory setting refs using strings is probably going to be removed at some point, and actually has some interesting drawbacks you might want to learn about. https://news.ycombinator.com/edit?id=12093234 – NJensen Mar 26 '19 at 18:47
13

You can do this in the router like that:

ReactDOM.render((
<Router onUpdate={() => window.scrollTo(0, 0)} history={browserHistory}>
     <Route path='/' component={App}>
        <IndexRoute component={Home}></IndexRoute>
        <Route path="/about" component={About}/>
        <Route path="/work">
            <IndexRoute component={Work}></IndexRoute>
            <Route path=":id" component={ProjectFull}></Route>
        </Route>
        <Route path="/blog" component={Blog}/>
    </Route>
 </Router>
), document.getElementById('root'));

The onUpdate={() => window.scrollTo(0, 0)} put the scroll top. For more information check: codepen link

Afaq Ahmed Khan
  • 2,164
  • 2
  • 29
  • 39
  • elegant solution that only requires a tiny code change in the router rather than having each component handle it itself. <3 – alengel Jul 21 '17 at 14:49
  • Unfortunately onUpdate fires with every new routeParam routed in a given route. So if you for instance have a page with a bunch of images, and if you could expand the image in a modal when clicked changing the the route to `/somePage/:imgId`, it will scroll up :(. Any way to "control" whether or not to fire the onUpdate event on specific routes/params? – connected_user Apr 12 '18 at 17:12
  • When I tried this, TypeScript complained that `onUpdate` does not exist in HashRouter's props... If anybody encounters the same issue: I ended up using the ScrollToTop solution described further down (and in the react-router docs) which worked perfectly for me. – Nicole Jul 27 '18 at 18:37
13

This works for me.

import React, { useEffect } from 'react';

useEffect(() => {
    const body = document.querySelector('#root');

    body.scrollIntoView({
        behavior: 'smooth'
    }, 500)

}, []);
bellabelle
  • 908
  • 7
  • 13
10

I have tried @sledgeweight solution but it does not work well for some of the views. But adding a setTimeout seems to work perfectly. In case someone facing the same issue as me. Below is my code.

import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'

const ScrollToTop = () => {
    const { pathname } = useLocation()
    useEffect(() => {
        console.log(pathname)
        /* settimeout make sure this run after components have rendered. This will help fixing bug for some views where scroll to top not working perfectly */
        setTimeout(() => {
            window.scrollTo({ top: 0, behavior: 'smooth' })
        }, 0)
    }, [pathname])
    return null
}

export default ScrollToTop

Use it in AppRouter.js as

<Router>
    <ScrollToTop/>
    <App>
</Router>
Akash Kumar Seth
  • 1,651
  • 1
  • 18
  • 22
9

Here's yet another approach that allows you to choose which mounted components you want the window scroll position to reset to without mass duplicating the ComponentDidUpdate/ComponentDidMount.

The example below is wrapping the Blog component with ScrollIntoView(), so that if the route changes when the Blog component is mounted, then the HOC's ComponentDidUpdate will update the window scroll position.

You can just as easily wrap it over the entire app, so that on any route change, it'll trigger a window reset.

ScrollIntoView.js

import React, { Component } from 'react';
import { withRouter } from 'react-router';

export default WrappedComponent => {
  class ResetWindowScroll extends Component {
    componentDidUpdate = (prevProps) => {
      if(this.props.location !== prevProps.location) window.scrollTo(0,0);
    }

    render = () => <WrappedComponent {...this.props} />
  }
  return withRouter(ResetWindowScroll);
}

Routes.js

import React from 'react';
import { Route, IndexRoute } from 'react-router';

import App from '../components/App';
import About from '../components/pages/About';
import Blog from '../components/pages/Blog'
import Index from '../components/Landing';
import NotFound from '../components/navigation/NotFound';
import ScrollIntoView from '../components/navigation/ScrollIntoView';

 export default (
    <Route path="/" component={App}>
        <IndexRoute component={Index} />
        <Route path="/about" component={About} /> 
        <Route path="/blog" component={ScrollIntoView(Blog)} />
        <Route path="*" component={NotFound} />
    </Route>
);

The above example works great, but if you've migrated to react-router-dom, then you can simplify the above by creating a HOC that wraps the component.

Once again, you could also just as easily wrap it over your routes (just change componentDidMount method to the componentDidUpdate method example code written above, as well as wrapping ScrollIntoView with withRouter).

containers/ScrollIntoView.js

import { PureComponent, Fragment } from "react";

class ScrollIntoView extends PureComponent {
  componentDidMount = () => window.scrollTo(0, 0);

  render = () => this.props.children
}

export default ScrollIntoView;

components/Home.js

import React from "react";
import ScrollIntoView from "../containers/ScrollIntoView";

export default () => (
  <ScrollIntoView>
    <div className="container">
      <p>
        Sample Text
      </p>
    </div>
  </ScrollIntoView>
);
Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51
9

This solution is working for the Functional component as well as the Class Base.

First of all, I do not like the idea of Scroll to top on every re-render, instead, I like of attache function to the particular event.

Step #1: Create a function to ScrollToTop

const scrollToTop = () => {
    window.scrollTo({
        top: 0,
        behavior: "smooth",
    });
};

Step #2: Call this function on an event e.g onClick

onRowClick={scrollToTop()}
// onClick={scrollToTop()}
// etc...
Rohit Nishad
  • 2,570
  • 2
  • 22
  • 32
8

I'm using react-router ScrollToTop Component which code described in react-router docs

https://reacttraining.com/react-router/web/guides/scroll-restoration/scroll-to-top

I'm changing code in single Routes file and after that no need of change code in every component.

Example Code -

Step 1 - create ScrollToTop.js Component

import React, { Component } from 'react';
import { withRouter } from 'react-router';

class ScrollToTop extends Component {
  componentDidUpdate(prevProps) {
    if (this.props.location !== prevProps.location) {
      window.scrollTo(0, 0)
    }
  }

  render() {
    return this.props.children
  }
}

export default withRouter(ScrollToTop)

Step 2 - In App.js file, add ScrollToTop Component after <Router

const App = () => (
  <Router>
    <ScrollToTop>
      <App/>
    </ScrollToTop>
  </Router>
)
Arpit
  • 1,423
  • 1
  • 17
  • 20
  • really good solution!if you have routes just render it at the top of your routes, but below Router.I didnt have to change every single component. – rash Jun 26 '20 at 05:54
8

All of the above didn't work for me - not sure why but:

componentDidMount(){
    document.getElementById('HEADER').scrollIntoView();
}

worked, where HEADER is the id of my header element

James Shiztar
  • 488
  • 5
  • 10
8

If all want to do is something simple here is a solution that will work for everybody

add this mini function

scrollTop()
{
    window.scrollTo({
        top: 0,
        behavior: "smooth"
    });
}

call the function as following from the footer of the page

<a className="scroll-to-top rounded" style={{display: "inline"}} onClick={this.scrollTop}>TOP</a>

if you want to add nice styles here is the css

.scroll-to-top {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  display: none;
  width: 2.75rem;
  height: 2.75rem;
  text-align: center;
  color: #fff;
  background: rgba(90, 92, 105, 0.5);
  line-height: 46px;
}
jerryurenaa
  • 3,863
  • 1
  • 27
  • 17
  • the code snippet doesn't seem to work. But the solution worked for me. Thanks and cheers! – sudonitin Apr 12 '20 at 08:33
  • @JohnVandivier maybe you are doing something wrong because we have tested this in almost all of the webs developed by our company. Please read and double-check again. – jerryurenaa Jun 08 '21 at 14:39
7

This is the only thing that worked for me (with an ES6 class component):

componentDidMount() {
  ReactDOM.findDOMNode(this).scrollIntoView();
}
danharsanyi
  • 416
  • 5
  • 5
7

I was doing a SPA in React 17.0 using functional components and window.scroll, window.scrollTo and all of this variants doesn't work for me. So I made a solution using useRef hook. I created a span tag in the top of the component with Ref and then I used and effect with ref.current.scrollIntoView()

There is a short example:

import React, { useEffect,useRef} from 'react';

export const ExampleComponent = () => {

  const ref = useRef();

  useEffect(() => {
      ref.current.scrollIntoView()
  }, []);

return(

 <>
   <span ref={ref}></span>
   <YourCodeHere />
   <MoreCode />
</>

) }

VrisToK
  • 61
  • 1
  • 2
6

Using Hooks in functional components, assuming the component updates when theres an update in the result props

import React, { useEffect } from 'react';

export const scrollTop = ({result}) => {
  useEffect(() => {
    window.scrollTo(0, 0);
  }, [result])
}
  • https://en.reactjs.org/docs/hooks-custom.html#extracting-a-custom-hook Don't forget, a hook name should start with the word `use` – CrsCaballero Nov 28 '19 at 20:07
6

The page that appears after clicking, just write into it.

  componentDidMount() {
    window.scrollTo(0, 0);
  } 
Muhammad Awais
  • 157
  • 2
  • 3
6

Smooth scroll to top . In hooks you can use this method inside lifecycle mounting state for once render

useEffect(() => {
  window.scrollTo({top: 0, left: 0, behavior: 'smooth' });
}, [])
sahil singh
  • 86
  • 1
  • 2
5

I tried everything, but this is the only thing that worked.

 useLayoutEffect(() => {
  document.getElementById("someID").scrollTo(0, 0);
 });
Alexandru Lupu
  • 281
  • 2
  • 9
5

Looks like all the useEffect examples dont factor in you might want to trigger this with a state change.

const [aStateVariable, setAStateVariable] = useState(false);

const handleClick = () => {
   setAStateVariable(true);
}

useEffect(() => {
  if(aStateVariable === true) {
    window.scrollTo(0, 0)
  }
}, [aStateVariable])
Andy
  • 679
  • 2
  • 10
  • 25
4

This is what I did:

useEffect(() => ref.current.scrollTo(0, 0));
const ref = useRef()

       return(
         <div ref={ref}>
           ...
         </div>
        )
Dharman
  • 30,962
  • 25
  • 85
  • 135
4

For React v18+ my recommendation will be to use wrapper component, will be the easiest way to execute.

Step 1: Create a ScrollToTop component (component/ScrollToTop.js)

import { useEffect } from "react";
import { useLocation } from "react-router-dom";

export function ScrollToTop() {
  const { pathname } = useLocation();

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

  return null;
}

Step 2: Wrap your App with it (index.js)

<React.StrictMode>
  <BrowserRouter>
    <ScrollToTop />
    <App />
  </BrowserRouter>
</React.StrictMode>

Explanation: Every time pathname changes useEffect will be called to scroll the page to the top.

Shubham Sarda
  • 539
  • 5
  • 10
3

I'm using React Hooks and wanted something re-usable but also something I could call at any time (rather than just after render).

// utils.js
export const useScrollToTop = (initialScrollState = false) => {
  const [scrollToTop, setScrollToTop] = useState(initialScrollState);

  useEffect(() => {
    if (scrollToTop) {
      setScrollToTop(false);
      try {
        window.scroll({
          top: 0,
          left: 0,
          behavior: 'smooth',
        });
      } catch (error) {
        window.scrollTo(0, 0);
      }
    }
  }, [scrollToTop, setScrollToTop]);

  return setScrollToTop;
};

Then to use the hook you can do:

import { useScrollToTop } from 'utils';

const MyPage = (props) => {
  // initialise useScrollToTop with true in order to scroll on page load 
  const setScrollToTop = useScrollToTop(true);

  ...

  return <div onClick={() => setScrollToTop(true)}>click me to scroll to top</div>
}
GavKilbride
  • 1,409
  • 15
  • 19
3

I ran into this issue building a site with Gatsby whose Link is built on top of Reach Router. It seems odd that this is a modification that has to be made rather than the default behaviour.

Anyway, I tried many of the solutions above and the only one that actually worked for me was:

document.getElementById("WhateverIdYouWantToScrollTo").scrollIntoView()

I put this in a useEffect but you could just as easily put it in componentDidMount or trigger it any other way you wanted to.

Not sure why window.scrollTo(0, 0) wouldn't work for me (and others).

jj0b
  • 1,106
  • 1
  • 12
  • 19
3

I had the same for problem for a while. Adding window.scrollTo(0, 0);to every page is painful and redundant. So i added a HOC which will wrap all my routes and it will stay inside BrowserRouter component:

 <ScrollTop>
    <Routes />
  </ScrollTop>

Inside ScrollTopComponent we have the following:

import React, { useEffect } from "react";
import { useLocation } from "react-router-dom";

const ScrollTop = (props) => {
  const { children } = props;

  const location = useLocation();

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

  return <main>{children}</main>;
};

export default ScrollTop;
Astrit Spanca
  • 643
  • 5
  • 13
3

Solution for functional component - Using useEffect() hook

 useEffect(() => {
window.history.scrollRestoration = 'manual';}, []);
2

If you are doing this for mobile, at least with chrome, you will see a white bar at the bottom.

This happens when the URL bar disappears. Solution:

Change the css for height/min-height: 100% to height/min-height: 100vh.

Google Developer Docs

Afaq Ahmed Khan
  • 2,164
  • 2
  • 29
  • 39
Artur Carvalho
  • 6,901
  • 10
  • 76
  • 105
2

None of the above answers is currently working for me. It turns out that .scrollTo is not as widely compatible as .scrollIntoView.

In our App.js, in componentWillMount() we added

this.props.history.listen((location, action) => {
        setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
    })

This is the only solution that is working universally for us. root is the ID of our App. The "smooth" behavior doesn't work on every browser / device. The 777 timeout is a bit conservative, but we load a lot of data on every page, so through testing this was necessary. A shorter 237 might work for most applications.

Todd
  • 583
  • 4
  • 10
2

For Functional components;

import React, {useRef} from 'react';
function ScrollingExample (props) {
// create our ref
const refToTop = useRef();

return (
<h1 ref={refToTop}> I wanna be seen </h1>
// then add enough contents to show scroll on page
<a onClick={()=>{
    setTimeout(() => { refToTop.current.scrollIntoView({ behavior: 'smooth' })}, 500)
        }}>  Take me to the element <a>
);
}
Baqer Naqvi
  • 6,011
  • 3
  • 50
  • 68
1
useEffect(() => {
    const body = document.querySelector('#root');

    body.scrollIntoView({
        behavior: 'smooth'
    }, 500)

}, []);

This best solution for view top scrolling page

or use ref to jump page

    // a link jump to page react
const ref = useRef(null);

  const handleClick = () => {
    ref.current?.scrollIntoView({behavior: 'smooth'});
  };

 <button onClick={handleClick}>Scroll to element</button>
 <div ref={ref}>Some content here</div>
Apurv
  • 21
  • 5
0

This code will cause a smooth behavior on the scroll:

<div onClick={() => {
   ReactDOM.findDOMNode(this.headerRef)
      .scrollIntoView({behavior: "smooth"});
                }} 
  className='go-up-button' >
</div>

You can pass other parameters inside the scrollIntoView() Following syntax can be used:

element.scrollIntoView();
element.scrollIntoView(alignToTop); // Boolean parameter
element.scrollIntoView(scrollIntoViewOptions); // Object parameter

alignToTop Optional Is a Boolean value:

If true, the top of the element will be aligned to the top of the visible area of the scrollable ancestor. Corresponds to scrollIntoViewOptions: {block: "start", inline: "nearest"}. This is the default value.
If false, the bottom of the element will be aligned to the bottom of the visible area of the scrollable ancestor. Corresponds to scrollIntoViewOptions: {block: "end", inline: "nearest"}.

scrollIntoViewOptions Optional Is an Object with the following properties:

*behavior* Optional
    Defines the transition animation.
    One of "auto", "instant", or "smooth". Defaults to "auto".
*block* Optional
    One of "start", "center", "end", or "nearest". Defaults to "center".
*inline* Optional
    One of "start", "center", "end", or "nearest". Defaults to "nearest".

More details can be found here: MDN docs

Afaq Ahmed Khan
  • 2,164
  • 2
  • 29
  • 39
Abhay Shiro
  • 3,431
  • 2
  • 16
  • 26
0

All the solutions talk about adding the scroll on componentDidMount or componentDidUpdate but with the DOM.

I did all of that and didn't worked.

So, figured out some other way that works just fine for me.

Added componentDidUpdate() { window.scrollTo(0, 0) } on the header, that mine is out of the <Switch></Switch> element. Just free in the app. Works.

I also found about some ScrollRestoration thing, but I'm lazy now. And for now going to keep it the "DidUpdate" way.

Dharman
  • 30,962
  • 25
  • 85
  • 135
0

None of the above answers is currently working for me. It turns out that .scrollTo is not as widely compatible as .scrollIntoView.

In our App.js, in componentWillMount() we added

    this.props.history.listen((location, action) => {
            setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777)
        })

This is the only solution that is working universally for us. root is the ID of our App. The "smooth" behavior doesn't work on every browser / device. The 777 timeout is a bit conservative, but we load a lot of data on every page, so through testing this was necessary. A shorter 237 might work for most applications.

Todd
  • 583
  • 4
  • 10
0

If I assume you are rendering a chapter of say, a book per page, all you need to do is add this to your code. This worked for me like magic.

    componentDidUpdate(prevProps) {
      if (prevProps.currentChapter !== this.props.currentChapter) {
        window.scrollTo(0, 0);
      }
    }

With this, you have no need creating a ref on the component being rendered.

0

I added an Event listener on the index.html page since it is through which all page loading and reloading is done. Below is the snippet.

// Event listener
addEventListener("load", function () {
    setTimeout(hideURLbar, 0);
}, false);
  
function hideURLbar() {
    window.scrollTo(0, 1);
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
-1

Something like this worked for me on a component:

<div ref="scroller" style={{height: 500, overflowX: "hidden", overflowY: "auto"}}>
      //Content Here
</div>

Then in whatever function is dealing with updates:

this.refs.scroller.scrollTop=0
kojow7
  • 10,308
  • 17
  • 80
  • 135
-4

Nothing worked for me but:

componentDidMount(){

    $( document ).ready(function() {
        window.scrollTo(0,0);
    });
}
gal007
  • 6,911
  • 8
  • 47
  • 70