React Router路由跳转新页面时自动滚动到顶部的实现方法
问题原因
你最初写的空依赖useEffect只会在组件首次挂载时执行一次,React Router 切换路由时如果匹配到的组件没有被卸载重建,这个 effect 根本不会重复触发,自然无法执行滚动逻辑。
推荐实现方案(基于React Hooks)
全局统一配置(一次配置全项目生效,最常用)
写一个无UI的公共滚动控制组件,靠React Router提供的useLocation钩子监听路由路径变化,只要路径变动就触发滚动到顶部:
import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; const ScrollToTop = () => { const { pathname } = useLocation(); useEffect(() => { window.scrollTo(0, 0); }, [pathname]); return null; }; export default 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> {/* 放在路由组件外层、Routes同级即可 */} <ScrollToTop /> <Routes> <Route path="/" element={<Home />} /> <Route path="/detail/:id" element={<Detail />} /> </Routes> </BrowserRouter> ); }
如果有个别页面不需要滚动到顶部,只需要在ScrollToTop组件的effect里加路径判断即可,比如匹配到带弹窗的路由时跳过滚动逻辑。
单页面单独控制
如果不需要全局生效,只需要在特定页面实现进入即滚动到顶部,直接在对应页面组件内用useLocation监听路径变化即可,不要使用空依赖数组:
import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; const TargetPage = () => { const { pathname } = useLocation(); useEffect(() => { // 需要平滑滚动可以替换为 window.scrollTo({ top: 0, behavior: 'smooth' }) window.scrollTo(0, 0); }, [pathname]); return <div>页面内容</div> };
注意事项
如果你的页面滚动容器不是全局window,而是某个设置了overflow: auto/scroll的内部DOM节点,需要通过useRef拿到对应容器实例,调用容器自身的scrollTo(0,0)方法,调用window对象的方法不会生效。
内容的提问来源于stack exchange,提问作者Husnain Mehmood
相关产品推荐
相关产品推荐

