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


当前回答

对我来说,是窗户。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")转到一条新路线时,我的屏幕会转到顶部

其他回答

一个可以添加到Route组件的React Hook。使用uselayouteeffect而不是自定义监听器。

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

export default function Routes() {
  const location = useLocation();
  // Scroll to top if path changes
  useLayoutEffect(() => {
    window.scrollTo(0, 0);
  }, [location.pathname]);

  return (
      <Switch>
        <Route exact path="/">

        </Route>
      </Switch>
  );
}

更新:更新到使用useLayoutEffect而不是useEffect,以减少视觉上的干扰。大致可以理解为:

useEffect:渲染组件->油漆到屏幕->滚动到顶部(运行效果) useLayoutEffect:渲染组件->滚动到顶部(运行效果)->油漆到屏幕

取决于您是在加载数据(考虑旋转器)还是有页面转换动画,useEffect可能更适合您。

render() {
    window.scrollTo(0, 0)
    ...
}

在道具没有改变和componentDidUpdate()没有触发的情况下,这是一个简单的解决方案。

平滑滚动选项

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

export default function ScrollToTop() {
  const { pathname } = useLocation();

  useEffect(() => {
    window.scrollTo({
      top: 0,
      left: 0,
      behavior: 'smooth', 
    });
  }, [pathname]);

  return null;
}

...

<Router>
      <ScrollToTop />
     ...
    </Router>

对于react-router-dom V5,滚动到顶部

    import React, { useEffect } from 'react';
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link,
    useLocation,
    withRouter
} from 'react-router-dom'
function _ScrollToTop(props) {
    const { pathname } = useLocation();
    useEffect(() => {
        window.scrollTo(0, 0);
    }, [pathname]);
    return props.children
}
const ScrollToTop = withRouter(_ScrollToTop)
function App() {
    return (
        <div>
            <Router>
                <ScrollToTop>
                    <Header />
                     <Content />
                    <Footer />
                </ScrollToTop>
            </Router>
        </div>
    )
}

利用钩子,你可以简单地在代码库的useEffect中插入window.scrollTo(0,0)。简单地在你的应用程序中实现代码片段,它应该在它的窗口顶部加载每个页面。

import { useEffect } from 'react';

useEffect(() => {
   window.scrollTo(0, 0);
}, []);