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


当前回答

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

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

其他回答

我的解决方案:我在我的屏幕组件中使用的组件(我想要滚动到顶部)。

import { useLayoutEffect } from 'react';

const ScrollToTop = () => {
    useLayoutEffect(() => {
        window.scrollTo(0, 0);
    }, []);

    return null;
};

export default ScrollToTop;

这可以在返回时保留滚动位置。 使用useEffect()对我来说是有bug的,当返回文档时,文档会滚动到顶部,当已经滚动的文档中的路由被更改时,也会有闪烁的效果。

我写了一个叫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);

一个可以添加到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可能更适合您。

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

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

这是我基于其他人在之前的文章中所做的方法。想知道在2020年使用位置作为依赖来防止重渲染是否是一个好方法吗?

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

function ScrollToTop( { children } ) {
    let location = useLocation();

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

    return children
}