如何在react router dom v6路由切换时自动滚动到页面顶部
react-router-dom v6 路由切换自动滚动到顶部解决方案
方案1:通用自定义组件方案(兼容所有v6版本)
该方案适配BrowserRouter/HashRouter所有使用场景,不受路由创建方式限制。
- 新建
ScrollToTop组件:
import { useEffect } from 'react' import { useLocation } from 'react-router-dom' const ScrollToTop = () => { const { pathname } = useLocation() useEffect(() => { // 全局window滚动到顶部 window.scrollTo({ top: 0, left: 0, behavior: 'instant' // 不需要滚动动画可以保留,要动画换成'smooth' }) // 若滚动容器为自定义DOM(如id为main-content的div),替换为以下逻辑 // const scrollContainer = document.getElementById('main-content') // if (scrollContainer) scrollContainer.scrollTop = 0 }, [pathname]) return null } export default ScrollToTop
- 组件引入配置:
必须将ScrollToTop放在路由组件的内部、路由表的外层,示例如下:
import { BrowserRouter, Routes, Route } from 'react-router-dom' import ScrollToTop from './ScrollToTop' import Home from './pages/Home' import Detail from './pages/Detail' function App() { return ( <BrowserRouter> <ScrollToTop /> {/* 必须放在此处,不能放到Routes内部 */} <Routes> <Route path="/" element={<Home />} /> <Route path="/detail/:id" element={<Detail />} /> {/* 其余路由配置 */} </Routes> </BrowserRouter> ) }
常见失效排查点
- 若页面需要异步请求数据后渲染,可将
useEffect替换为useLayoutEffect,或在数据请求完成的回调中补充滚动到顶部的逻辑 - 检查滚动容器是否为
window,如果是嵌套滚动容器需要更换为对应容器的滚动属性设置 - React 18严格模式下开发环境
useEffect会执行两次,属于正常现象,不影响生产环境效果
方案2:v6.4+ 数据路由专属最简方案
如果你使用createBrowserRouter创建数据路由,无需自定义组件,直接在路由配置中添加内置属性即可:
import { createBrowserRouter, RouterProvider } from 'react-router-dom' import Home from './pages/Home' import Detail from './pages/Detail' const router = createBrowserRouter([ { path: '/', element: <Home /> }, { path: '/detail/:id', element: <Detail /> }, // 其余路由配置 ], { scrollRestoration: 'top' // 开启全局路由切换自动滚动到顶部 }) function App() { return <RouterProvider router={router} /> }
如果需要针对单个路由自定义滚动行为,可以使用useScrollRestoration钩子做特殊处理。
内容的提问来源于stack exchange,提问作者jethro-dev
相关产品推荐
相关产品推荐

