【问题标题】:reactjs scrolling to top doesn't work after rendering渲染后reactjs滚动到顶部不起作用
【发布时间】:2020-02-24 10:28:27
【问题描述】:

我对 reactjs 很陌生,我想在路由更改后滚动到页面顶部。我已经尝试了几乎所有的可能性来实现这一点,但没有运气。我已经花了 2 多天的时间,我决定把它贴在这里,因为有数十亿个重复。我正在使用 react: v16.12, redux: v4, react-router-dom: v5.1

我在这些帖子中尝试过任何东西:

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

这是我的 App.js(我知道它需要稍微重构一下)

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

这是我的 ScrollIntoView.js 工具:

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)

所以我也尝试过 useEffect()、oaf 包和历史记录,但没有运气。我在 ScrollIntoView 组件中添加了 console.log('hello');,它会在路线更改时触发,但不会向上滚动。我想知道它是否被某种东西覆盖了。任何提示和建议将不胜感激。感谢您的时间和关注。

【问题讨论】:

  • this.props.children 是什么?请告诉我
  • 因为您没有通过调用附加到窗口的函数遇到未定义的错误,并且您的控制台日志正在按预期工作;我很好奇您的窗口高度和/或 CSS 是否存在问题。如果您发布了相关的 CSS,则可以诊断!看到这个答案:stackoverflow.com/a/18573599/10437471我对下一个问题的解决方案不满意,但它们对调试很有帮助:stackoverflow.com/questions/46018212/…
  • @BEVR1337 我也试过了。我只有 overflow-x: hidden 。我按照您上面提到的解决方案,它没有工作。

标签: reactjs redux react-router-dom


【解决方案1】:

你检查过有没有窗户?

if (typeof window !== 'undefined') {
  window.scrollTo(0,0);
} 

【讨论】:

  • 如果 window 未定义,则调用 scrollTo 会引发错误。原始帖子中没有错误边界,因此如果未定义窗口,它应该关闭整个反应应用程序。 OP 说什么也没发生,没有错误或崩溃。
  • 有一个窗口对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 2013-05-26
  • 1970-01-01
  • 2015-08-02
  • 1970-01-01
相关资源
最近更新 更多