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


当前回答

这个答案是遗留代码,对于路由器v4+检查其他答案

<Router onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}>
  ...
</Router>

如果它不起作用,你应该找到原因。同样在componentDidMount内部

document.body.scrollTop = 0;
// or
window.scrollTo(0,0);

你可以用:

componentDidUpdate() {
  window.scrollTo(0,0);
}

你可以添加一些像" scrolling = false"这样的标志,然后在update中:

componentDidUpdate() {
  if(this.scrolled === false){
    window.scrollTo(0,0);
    scrolled = true;
  }
}

其他回答

对于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>
    )
}

我的申请也遇到了同样的问题。使用下面的代码片段可以帮助我在单击下一个按钮时滚动到页面顶部。

<Router onUpdate={() => window.scrollTo(0, 0)} history= {browserHistory}>
...
</Router>

然而,在浏览器返回时,这个问题仍然存在。经过大量的尝试,我意识到这是因为浏览器窗口的历史对象,它有一个属性scrollRestoration被设置为auto。将此设置为手动解决了我的问题。

function scrollToTop() {
    window.scrollTo(0, 0)
    if ('scrollRestoration' in history) {
        history.scrollRestoration = 'manual';
    }
}

<Router onUpdate= {scrollToTop} history={browserHistory}>
....
</Router>

在主组件中。

只需添加这个React钩子(如果你没有使用React类):

const oldPage = useRef(pathname)

useEffect(() => {
  if (pathname !== oldPage.current) {
    try {
      window.scroll({
        top: 0,
        left: 0,
        behavior: 'smooth'
      })
    } catch (error) {
      // for older browser
      window.scrollTo(0, 0)
    }
    oldPage.current = pathname
  }
}, [pathname])

平滑滚动选项

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>

我写了一个叫withScrollToTop的高阶组件。这个HOC有两个标志:

onComponentWillMount -导航时是否滚动到顶部(componentWillMount) onComponentDidUpdate—是否在更新时滚动到顶部(componentDidUpdate)。该标志在组件没有卸载但发生导航事件的情况下是必要的,例如,从/users/1到/users/2。


// @flow
import type { Location } from 'react-router-dom';
import type { ComponentType } from 'react';

import React, { Component } from 'react';
import { withRouter } from 'react-router-dom';

type Props = {
  location: Location,
};

type Options = {
  onComponentWillMount?: boolean,
  onComponentDidUpdate?: boolean,
};

const defaultOptions: Options = {
  onComponentWillMount: true,
  onComponentDidUpdate: true,
};

function scrollToTop() {
  window.scrollTo(0, 0);
}

const withScrollToTop = (WrappedComponent: ComponentType, options: Options = defaultOptions) => {
  return class withScrollToTopComponent extends Component<Props> {
    props: Props;

    componentWillMount() {
      if (options.onComponentWillMount) {
        scrollToTop();
      }
    }

    componentDidUpdate(prevProps: Props) {
      if (options.onComponentDidUpdate &&
        this.props.location.pathname !== prevProps.location.pathname) {
        scrollToTop();
      }
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  };
};

export default (WrappedComponent: ComponentType, options?: Options) => {
  return withRouter(withScrollToTop(WrappedComponent, options));
};

使用它:

import withScrollToTop from './withScrollToTop';

function MyComponent() { ... }

export default withScrollToTop(MyComponent);