我有一个问题,当导航到另一个页面,它的位置将保持像之前的页面。所以它不会自动滚动到顶部。 我也试过使用window。onChange路由器上的scrollTo(0,0)。我还使用了scrollBehavior来修复这个问题,但它没有工作。对此有什么建议吗?
当前回答
因为,我使用功能组件,这里是我如何设法实现它。
import { useEffect } from 'react';
import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom';
function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return null;
}
const IndexRoutes = () => {
return (
<BrowserRouter>
<ScrollToTop />
<Routes>
<Route exact path="/">
<Home />
</Route>
/* list other routes below */
</Routes>
</BrowserRouter>
);
};
export default IndexRoutes;
您也可以从下面的链接中参考代码
https://reactrouter.com/web/guides/scroll-restoration
其他回答
但是课程太2018年了
ScrollToTop实现与React挂钩
ScrollToTop.js
import { useEffect } from 'react';
import { withRouter } from 'react-router-dom';
function ScrollToTop({ history }) {
useEffect(() => {
const unlisten = history.listen(() => {
window.scrollTo(0, 0);
});
return () => {
unlisten();
}
}, []);
return (null);
}
export default withRouter(ScrollToTop);
用法:
<Router>
<Fragment>
<ScrollToTop />
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</Fragment>
</Router>
ScrollToTop也可以实现为一个包装器组件:
ScrollToTop.js
import React, { useEffect, Fragment } from 'react';
import { withRouter } from 'react-router-dom';
function ScrollToTop({ history, children }) {
useEffect(() => {
const unlisten = history.listen(() => {
window.scrollTo(0, 0);
});
return () => {
unlisten();
}
}, []);
return <Fragment>{children}</Fragment>;
}
export default withRouter(ScrollToTop);
用法:
<Router>
<ScrollToTop>
<Switch>
<Route path="/" exact component={Home} />
</Switch>
</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);
对于较小的应用程序,有1-4个路由,你可以尝试用#id重定向到顶部DOM元素,而不仅仅是一个路由。这样就不需要在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;
对我来说,是窗户。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")转到一条新路线时,我的屏幕会转到顶部