如何使用react router dom v6滚动到路由更改的顶部?
我已经尝试过,每次转换时都会将路由器滚动到顶部,这是我在使用react-router-dom
v5时使页面在路由更改时滚动到顶部的解决方案。现在,我使用的是react-router-dom
v6,但此解决方案不起作用。
我尝试了React路由器v6窗口.scrollTo不工作,也不适合我。
我试过了https://github.com/remix-run/react-router/issues/7365,即使用preload
道具来触发scrollTo(0,0)
,对我来说也不起作用
我真的不确定你的布局是什么样子,但在<BrowserRouter />
中,你可以用包装器包装你的应用程序,并检查useLayoutEffect
中的位置变化。然后,如果有变化,您可以滚动到顶部。这是一个粗略的例子。
Codesandbox
import { BrowserRouter, Routes, Route, Link, useLocation } from 'react-router-dom'
import { useLayoutEffect } from 'react'
const Wrapper = ({children}) => {
const location = useLocation();
useLayoutEffect(() => {
document.documentElement.scrollTo(0, 0);
}, [location.pathname]);
return children
}
const Component = ({title}) => {
return (
<div>
<p style={{paddingTop: '150vh'}}>{title}</p>
</div>
)
}
const App = () => {
return (
<BrowserRouter>
<Wrapper>
<p>Scroll the bottom to change pages</p>
<Routes>
<Route path="/" element={<Component title="Home"/>} />
<Route path="/about" element={<Component title="About"/>} />
<Route path="/product" element={<Component title="Product"/>} />
</Routes>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
<Link to="/product">Product</Link>
</Wrapper>
</BrowserRouter>
)
}
export default App
本文解决了这个问题查看它->https://www.matthewhoelter.com/2022/04/02/how-to-scroll-to-top-on-route-change-with-react-router-dom-v6.html
使滚动到顶部组件
然后在初始中添加此代码
import { useLocation } from "react-router-dom";
export default function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
// "document.documentElement.scrollTo" is the magic for React Router Dom v6
document.documentElement.scrollTo({
top: 0,
left: 0,
behavior: "instant", // Optional if you want to skip the scrolling animation
});
}, [pathname]);
return null;
}
然后在你的App.js中导入它,现在你的问题已经解决了
参见img
在更新版本的react中无法访问窗口函数,最好使用useRef Hook。
const myRef = useRef<any>(null);
const executeScroll = () => myRef.current.scrollIntoView({inline: "center"});
useEffect(() => {
executeScroll();
}, [location.pathname]);
// YOUR COMPONENTS CODE
// I have my toolbar as the ref
<Toolbar ref={myRef}/>
当使用useNavigator并且路径名发生更改时,此选项将滚动。
我使用滚动恢复。我试过了,如果不使用ScrollRestoration组件,window.sollTo(0,0(不起作用。
import { Outlet, useLocation, ScrollRestoration } from 'react-router-dom'
function App() {
const { pathname } = useLocation()
useLayoutEffect(() => {
window.scrollTo(0, 0)
}, [pathname])
return (
<div className="App">
<TopHeader />
<Outlet />
<Footer />
<ScrollRestoration />
</div>
)
}
export default App
const scrollToPosition = (top = 0) => {
try {
/**
* Latest API
*/
window.scroll({
top: top,
left: 0,
behavior: "smooth",
});
} catch (_) {
/**
* Fallback
*/
window.scrollTo(0, top);
}
};
您可以使用上面的代码向上滚动。
const didMount = useDidMount();
const router = useRouter();
const { asPath } = router;
useEffect(() => {
if (didMount) {
scrollToPosition();
}
}, [asPath]);
并将上面的代码添加到顶部父组件中。
为了不仅在导航到新页面时将滚动位置重置为顶部,而且在返回到前一页面时保持旧的滚动位置,请使用ScrollRestoration
组件(自React Router 6.4起(。
加载程序完成后,该组件将模拟浏览器在位置更改时的滚动恢复,以确保滚动位置恢复到正确的位置,即使是跨域。
只需在应用程序的根组件中渲染一次即可。下面是一个带有功能组件的示例:
import { ScrollRestoration } from 'react-router-dom';
function App() {
return <>
<div>Some content</div>
<ScrollRestoration/>
</>;
}