我有一个问题,当导航到另一个页面,它的位置将保持像之前的页面。所以它不会自动滚动到顶部。 我也试过使用window。onChange路由器上的scrollTo(0,0)。我还使用了scrollBehavior来修复这个问题,但它没有工作。对此有什么建议吗?


当前回答

对于'REACT-ROUTER-DOM v6及以上'

我通过创建一个包装器函数并将其包装在所有路由上解决了以下问题。

请遵循以下步骤:

1:需要导入以下内容:

import {Routes, Route, BrowserRouter as Router, useLocation} from 'react-router-dom';
import {useLayoutEffect} from 'react';

2:在"App"函数上面写一个包装器函数:

const Wrapper = ({children}) => {
  const location = useLocation();
  useLayoutEffect(() => {
    document.documentElement.scrollTo(0, 0);
  }, [location.pathname]);
  return children
} 

3:现在在包装器函数中包装你的路由:

<BrowserRouter>
  <Wrapper>
    <Navbar />
      <Routes>
        <Route exact path="/" element={<Home/>} />
        <Route path="/Products" element={<Products/>} />
        <Route path="/Login" element={<Login/>} />
        <Route path="/Aggressive" element={<Aggressive/>} />
        <Route path="/Attendance" element={<Attendance/>} />
        <Route path="/Choking" element={<Choking/>} />
        <Route path="/EmptyCounter" element={<EmptyCounter/>} />
        <Route path="/FaceMask" element={<FaceMask/>} />
        <Route path="/Fainting" element={<Fainting/>} />
        <Route path="/Smoking" element={<Smoking/>} />
        <Route path="/SocialDistancing" element={<SocialDistancing/>} />
        <Route path="/Weapon" element={<Weapon/>} />
      </Routes>
    <Footer />
  </Wrapper>
</BrowserRouter>

这应该能解决问题。

其他回答

这个答案只适用于v4版本,而不适用于后续版本。

React Router v4的文档包含了用于滚动恢复的代码示例。下面是他们的第一个代码示例,它作为一个全站解决方案,当页面导航到“滚动到顶部”:

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)

然后在你的应用程序的顶部渲染它,但在路由器下面:

const App = () => (
  <Router>
    <ScrollToTop>
      <App/>
    </ScrollToTop>
  </Router>
)

// or just render it bare anywhere you want, but just one :)
<ScrollToTop/>

^直接从文档中复制

显然,这适用于大多数情况,但是关于如何处理选项卡接口以及为什么没有实现通用解决方案还有更多内容。

React挂钩2020:)

import React, { useLayoutEffect } from 'react';
import { useLocation } from 'react-router-dom';

const ScrollToTop: React.FC = () => {
  const { pathname } = useLocation();
  useLayoutEffect(() => {
    window.scrollTo(0, 0);
  }, [pathname]);

  return null;
};

export default ScrollToTop;

我唯一的解决方案是在每个文件中添加一行代码,例如:

import React from 'react';
const file = () => { document.body.scrollTop = 0; return( <div></div> ) }

对我来说,是窗户。scrollTo(0,0)和document.documentElement。scrollTo(0,0)没有在我的所有屏幕上工作(只在一个屏幕上工作)。

然后,我意识到我的屏幕的溢出(滚动是允许的)不在窗口(因为我们有一些静态点,所以我们把溢出:auto在其他div)。

为了实现这一点,我做了以下测试:

useEffect(() => {
  const unlisten = history.listen(() => {
    console.log(document.documentElement.scrollTop)
    console.log(window.scrollTop)
    window.scrollTo(0, 0);
  });
  return () => {
    unlisten();
  }
}, []);

在所有的对数中,我得到0。

所以,我寻找我有滚动的容器,并放置一个id:

<div id="SOME-ID">
    ...
</div>

在我的ScrollToTop组件中,我放入:

useEffect(() => {
  const unlisten = history.listen(() => {
    window.scrollTo(0, 0);
    document.getElementById("SOME-ID")?.scrollTo(0, 0)
  });
  return () => {
    unlisten();
  }
}, []);

现在,当我用history.push("/SOME-ROUTE")转到一条新路线时,我的屏幕会转到顶部

2021年(React 16) -基于@Atombit的评论

下方卷轴向上,还保留了历史卷轴位置。

function ScrollToTop() {
  const history = useHistory()
  useEffect(() => {
    const unlisten = history.listen((location, action) => {
      if (action !== 'POP') {
        window.scrollTo(0, 0)
      }
    })
    return () => unlisten()
  }, [])
  return (null)
}

用法:

<Router>
  <ScrollToTop />
  <Switch>
    <Route path="/" exact component={Home} />
  </Switch>
</Router>