在导航更改时滚动恢复到顶部
Posted
技术标签:
【中文标题】在导航更改时滚动恢复到顶部【英文标题】: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。
【问题讨论】:
【参考方案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 如果你真的想保持一切挂钩方式以上是关于在导航更改时滚动恢复到顶部的主要内容,如果未能解决你的问题,请参考以下文章