1

I am pretty new to reactjs and I want to scroll to the top of the page after the route changes. I have tried almost every single possibilities to accomplish this but no luck. I have spent over 2 days and I have decided to post it here shamefully since there are billions of duplicates. I am using react: v16.12, redux: v4, react-router-dom: v5.1

I have tried anything in these posts:

Scroll to the top of the page after render in react.js

https://gist.github.com/romanonthego/223d2efe17b72098326c82718f283adb

react-router scroll to top on every transition

This is my App.js ( I know it needs to be refactored a little bit )

import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import jwt_decode from "jwt-decode";
import setAuthToken from "utils/setAuthToken";
import {
  setCurrentUser,
  logoutUser,
  getNotifications
} from "actions/authActions";
import { clearCurrentProfile } from "actions/profileActions";

// import { ApolloProvider } from 'react-apollo';
// import { ApolloClient } from 'apollo-client';
// import { HttpLink } from 'apollo-link-http';
// import { InMemoryCache } from 'apollo-cache-inmemory';
import store from "store";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import ScrollIntoView from "../appUtils/ScrollIntoView";


// Check for token
if (localStorage.jwtToken) {
  // Set auth token header auth
  setAuthToken(localStorage.jwtToken);
  // Decode token and get user info and exp
  const decoded = jwt_decode(localStorage.jwtToken);
  // Set user and isAuthenticated
  store.dispatch(setCurrentUser(decoded));
  store.dispatch(getNotifications(decoded.id));
  // Check for expired token
  const currentTime = Date.now() / 1000;
  if (decoded.exp < currentTime) {
    // Logout user
    store.dispatch(logoutUser());
    // Clear current Profile
    store.dispatch(clearCurrentProfile());
    // Redirect to login
    window.location.href = "/login";
  }
}

class App extends Component {
  static propTypes = {
    auth: PropTypes.object.isRequired
  };

  isClient = () => typeof window !== "undefined";

  render() {
    const { auth } = this.props;
    const user = auth && auth.user ? auth.user : null;

    const adminRoutes = () => (
      <div>
        <Switch>
          <PrivateRoute exact path="/admin" component={Admin} />

          <PrivateRoute
            exact
            path="/admin/credential"
            component={UserCredentialList}
          />

          <PrivateRoute
            exact
            path="/admin/user/credential/:id"
            component={UserCredential}
          />

          <PrivateRoute
            exact
            path="/admin/deactivate"
            component={UserDeactivateList}
          />

          <PrivateRoute
            exact
            path="/admin/user/deactivate/:id"
            component={UserDeactivate}
          />
        </Switch>
      </div>
    );

    return (
      <div className={styles["app-wrapper"]}>
        <Router>
          <ScrollIntoView>
          <Navbar />
          <React.Fragment>
            <div className={styles["content-wrapper"]}>
              <Route exact path="/" component={Landing} />
                <Switch>
                  <Route exact path="/register" component={Register} />
                  <Route exact path="/login" component={Login} />
                  <Route exact path="/thank-you" component={ThankYouPage} />
                  <Route exact path="/sign-out" component={SignoutPage} />
                  <Route
                    exact
                    path="/password/recover"
                    component={RecoverPassword}
                  />
                  <Route
                    exact
                    path="/password/reset/:userId/:token"
                    component={UpdatePassword}
                  />
                  <Route
                    exact
                    path="/notifications"
                    component={Notifications}
                  />
                </Switch>

                <Switch>
                  <PrivateRoute
                    exact
                    path="/profiles"
                    component={ProfilesLandingPage}
                  />
                  <PrivateRoute
                    exact
                    path="/specialists"
                    component={SpecialistsPage}
                  />
                  <PrivateRoute
                    exact
                    path="/profile/:handle"
                    component={Profile}
                  />
                  {user && user.isAdmin && adminRoutes()}
                  <PrivateRoute exact path="/dashboard" component={Dashboard} />
                  {/* <Switch>
                <PrivateRoute exact path="/messages" component={Messages} />
              </Switch> */}
                  <PrivateRoute
                    exact
                    path="/create-profile"
                    component={CreateProfile}
                  />
                  <PrivateRoute
                    exact
                    path="/edit-profile"
                    component={EditProfile}
                  />
                  <PrivateRoute
                    exact
                    path="/edit-account"
                    component={EditAccount}
                  />
                  <PrivateRoute
                    exact
                    path="/change-password"
                    component={ChangePassword}
                  />
                  <PrivateRoute
                    exact
                    path="/add-experience"
                    component={AddExperience}
                  />
                  <PrivateRoute
                    exact
                    path="/add-education"
                    component={AddEducation}
                  />
                  {/* <PrivateRoute
                      exact
                      path="/add-payment"
                      component={AddPayment}
                    />
                    <PrivateRoute
                      exact
                      path="/update-payment"
                      component={UpdatePayment}
                    /> */}
                  <PrivateRoute exact path="/public-qa" component={PostsPage} />
                  <PrivateRoute
                    exact
                    path="/post/edit/:id"
                    component={PostEdit}
                  />
                  <PrivateRoute
                    exact
                    path="/ask-question"
                    component={PostForm}
                  />
                  <PrivateRoute
                    exact
                    path="/create-case"
                    component={CreateCase}
                  />
                  <PrivateRoute
                    exact
                    path="/contact-messages"
                    component={ContactMessagesPage}
                  />
                  <PrivateRoute
                    exact
                    path="/contact-messages/:id"
                    component={ContactMessageItem}
                  />
                  {/* <Switch>
                  <PrivateRoute
                    exact
                    path="/cases"
                    component={CaseLandingPage}
                  />
                </Switch> */}
                  <PrivateRoute
                    exact
                    path="/your-cases"
                    component={YourCasesPage}
                  />
                  <PrivateRoute
                    exact
                    path="/case/:id"
                    component={CaseDetails}
                  />
                  <PrivateRoute
                    exact
                    path="/post/:id"
                    component={PostDetails}
                  />
                </Switch>

                <Route exact path="/not-found" component={NotFound} />
                <FooterRoutes />
            </div>
          </React.Fragment>
          <Footer />
          </ScrollIntoView>
        </Router>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    auth: state.auth
  };
}

export default connect(mapStateToProps)(App);

and this is my ScrollIntoView.js util:

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

class ScrollIntoView extends Component {
  componentDidUpdate(prevProps) {
    if (this.props.location !== prevProps.location) {
      window.scrollTo(0,0);
      console.log('hello world')
    }
  }

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

export default withRouter(ScrollIntoView)

So I have tried with useEffect(), oaf package and history as well but no luck. I added console.log('hello'); in ScrollIntoView component, it triggers whenever the route changes but It doesn't scroll up to top. I wonder if it is overwritten by something somehow. Any hint & advice will be highly appreciated. Thank you for your time and attention.

  • what is this.props.children ?can you please tell – warmachine Feb 24 '20 at 10:43
  • Since you aren't experiencing an undefined error by calling a function attached to window, and you're console logging is working when expected; I am curious if there is an issue with your window's height and/or CSS. If you posted the relevant CSS, that could be diagnosed! See this answer: https://stackoverflow.com/a/18573599/10437471 I'm not satisfied with solutions in this next question, but they are helpful for debugging: https://stackoverflow.com/questions/46018212/scrollto-function-does-nothing – BEVR1337 Feb 24 '20 at 14:41
  • @BEVR1337 I have tried that too. I had overflow-x: hidden only. I followed the solution you mentioned above, it didnt work. – interstellar Feb 24 '20 at 18:36

1 Answers1

0

Have you checked if there is a window?

if (typeof window !== 'undefined') {
  window.scrollTo(0,0);
} 
Osman Safak
  • 255
  • 1
  • 5
  • If window is undefined, then calling scrollTo would throw an error. There's no error boundary in the original post, so it should bring down the entire react app if window was undefined. OP says nothing happens, no errors or crashing. – BEVR1337 Feb 24 '20 at 14:44
  • There is a window object. – interstellar Feb 24 '20 at 18:38