【问题标题】:Scroll restore to top on navigation change在导航更改时滚动恢复到顶部
【发布时间】:2019-08-02 08:58:21
【问题描述】:

我在使用 react-router 导航时遇到滚动问题。

当我导航到不同的组件时,它会保持上次导航的滚动位置。但是,我希望它在导航更改时恢复并从顶部开始。

 class App extends Component{
  render() {
   return(
    <BrowserRouter onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}>
      <div style={{display: 'flex'}}>
        <div className='navBar'>
          <ul style={{listStyleType: 'none'}}>
            <li><Link to='/'>Home</Link></li>
            <li><Link to='/towns'>Towns</Link></li>
            <li><Link to='/pubs'>Pubs</Link></li>
            <li><Link to='/venues'>Venues</Link></li>
            <li><Link to='/cinemas'>Cinemas</Link></li>

          </ul>
        </div>

        <div style={{flex:1, padding:'0px'}}>
          {routes.map((route) => (
            <Route
              key={route.path}
              path={route.path}
              exact={route.exact}
              component={route.main}
              />
            ))}
          </div>
        </div>
      </BrowserRouter>
     )
   }
 }

但是它不起作用。我感觉问题出在我的导航风格上,而不是 window.scrollTo() sn-p。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    据我所知,由于 react-router v4,BrowserRouter 没有 onUpdate 功能。

    实现它的几种方法。这将是最简单的...

    components/ScrollIntoView.js

    import { PureComponent } from "react";
    import { withRouter } from "react-router-dom";
    
    class ScrollIntoView extends PureComponent {
      componentDidMount = () => window.scrollTo(0, 0);
    
      componentDidUpdate = prevProps => {
        if (this.props.location.pathname !== prevProps.location.pathname) window.scrollTo(0, 0);
      };
    
      render = () => this.props.children;
    }
    
    export default withRouter(ScrollIntoView);
    

    routes/index.js

    import React from "react";
    import { BrowserRouter, Route, Switch } from "react-router-dom";
    import Links from "../components/Links";
    import Home from "../components/Home";
    import About from "../components/About";
    import Contact from "../components/Contact";
    import ScrollIntoView from "../components/ScrollIntoView";
    
    export default () => (
      <BrowserRouter>
        <div>
          <ScrollIntoView>
            <Links />
            <Switch>
              <Route exact path="/" component={Home} />
              <Route path="/about" component={About} />
              <Route path="/contact" component={Contact} />
            </Switch>
            <Links />
          </ScrollIntoView>
        </div>
      </BrowserRouter>
    );
    

    或者你可以在这里找到另一种方法:Scroll to the top of the page after render in react.js

    【讨论】:

    • 优秀的@Matt Carlotta。工作完美。唯一我可能想要改变的是,以某种方式使它,所以如果我再次点击以前的导航,让它记住我在哪里。但是,目前这不是一个大问题,您的回答已经达到了目标。谢谢。
    • 这只有在第一次访问页面时才有效,如何做到每次都这样做?提前谢谢你
    • 这个答案相当陈旧,并且使用 location 对象而不是 location.pathname 字符串包含错误。也就是说,我已经更新了答案,但是,如果可能的话,我强烈建议使用 react-router-dom 的 useLocation 钩子和 useEffect
    【解决方案2】:

    我使用 React hooks 的解决方案

    import { useEffect, useRef } from 'react';
    import { withRouter } from 'react-router-dom';
    import PropTypes from 'prop-types';
    
    const ScrollIntoView = ({ children, location }) => {
      const prevLocation = useRef();
    
      useEffect(() => {
        if (prevLocation.current !== location.pathname) {
          window.scrollTo(0, 0);
          prevLocation.current = location.pathname;
        }
      }, [location]);
    
      return children;
    };
    
    ScrollIntoView.propTypes = {
      children: PropTypes.node,
      location: PropTypes.object
    };
    
    export default withRouter(ScrollIntoView);
    
    

    【讨论】:

    • useLocation() 而不是 withRouter 如果你真的想保持一切挂钩方式
    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    相关资源
    最近更新 更多