React Hooks项目中回退导航后恢复滚动位置的实现方案咨询
实现函数组件中回退导航的滚动位置恢复
我之前为了搞定回退导航后恢复滚动位置这个问题,搜了好几个相关的解决方案,但无奈找到的可行方案全是基于类组件实现的。后来我自己摸索出了在函数组件里实现这个功能的方法,下面把思路和代码分享给大家:
核心实现思路
- 用
useEffect监听路由变化,在页面滚动时记录当前路由对应的滚动位置 - 借助
sessionStorage持久化存储滚动数据——毕竟回退导航时原页面组件可能已经卸载,内存存储会丢失 - 当路由切回之前的页面时,从存储中取出对应的滚动位置,执行滚动恢复操作
完整代码示例
import { useEffect, useRef } from 'react'; import { useLocation } from 'react-router-dom'; const ScrollRestoration = () => { const location = useLocation(); const scrollPositions = useRef({}); // 监听页面滚动,实时保存当前路由的滚动位置 useEffect(() => { const saveScrollPosition = () => { scrollPositions.current[location.pathname] = window.scrollY; sessionStorage.setItem('scrollPositions', JSON.stringify(scrollPositions.current)); }; window.addEventListener('scroll', saveScrollPosition); return () => { window.removeEventListener('scroll', saveScrollPosition); }; }, [location.pathname]); // 路由切换时,恢复对应页面的滚动位置 useEffect(() => { const savedPositions = JSON.parse(sessionStorage.getItem('scrollPositions')) || {}; if (savedPositions[location.pathname]) { window.scrollTo(0, savedPositions[location.pathname]); } else { window.scrollTo(0, 0); } }, [location.pathname]); return null; }; export default ScrollRestoration;
使用方式
把这个组件放在你的路由根组件(比如App.jsx)中,让它能全局监听路由变化:
import { BrowserRouter as Router } from 'react-router-dom'; import ScrollRestoration from './ScrollRestoration'; function App() { return ( <Router> <ScrollRestoration /> {/* 你的其他路由页面组件 */} </Router> ); }
这个方案的优点:
- 完全基于函数组件和Hooks实现,贴合现代React开发模式
- 用
sessionStorage持久化数据,即使页面刷新也能保留滚动位置 - 全局监听路由,无需在每个页面单独添加逻辑
内容的提问来源于stack exchange,提问作者Mukhriddin Shakhriyorov
相关产品推荐
相关产品推荐

