v6路由跳转时页面滚动位置异常排查分享

BigNet +0/-0 0 0 正常 2025-12-24T07:01:19 React-Router

最近在项目中将React Router从v5升级到v6,遇到了一个令人头疼的问题:页面跳转时滚动位置异常。这个问题在v5中从未出现过。

问题复现步骤:

  1. 在长页面中滚动到中间位置
  2. 点击路由链接跳转到另一个页面
  3. 返回上一页,发现页面不是停留在之前的滚动位置

排查过程: 最初以为是组件状态管理的问题,检查了useEffect和useState的使用。后来发现v6的useNavigateuseLocation行为确实有变化,特别是与滚动相关的逻辑。

解决方案: 在项目中添加了自定义滚动恢复逻辑:

import { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';

function ScrollToTop() {
  const location = useLocation();
  const navigate = useNavigate();

  useEffect(() => {
    // 保存当前滚动位置
    const saveScrollPosition = () => {
      sessionStorage.setItem('scrollPosition', window.scrollY);
    };

    // 恢复滚动位置
    const restoreScrollPosition = () => {
      const position = sessionStorage.getItem('scrollPosition');
      if (position) {
        window.scrollTo(0, parseInt(position));
      }
    };

    // 监听页面离开事件
    window.addEventListener('beforeunload', saveScrollPosition);
    
    // 页面加载时恢复位置
    restoreScrollPosition();

    return () => {
      window.removeEventListener('beforeunload', saveScrollPosition);
    };
  }, [location.pathname]);

  return null;
}

总结: v6版本的路由行为确实有变化,建议在升级时重点关注滚动位置相关逻辑,必要时需要手动处理。这个问题在实际项目中影响用户体验较大,值得特别关注。

推广
广告位招租

讨论

0/2000
神秘剑客1
神秘剑客1 · 2026-01-08T10:24:58
v6的滚动行为确实变了,但用sessionStorage存位置太粗糙了,建议结合useScrollRestoration或自定义hook更优雅地处理。
落花无声
落花无声 · 2026-01-08T10:24:58
这个方案治标不治本,真正的问题是React Router v6默认不自动恢复滚动位置,应该在文档里明确说明。
心灵捕手1
心灵捕手1 · 2026-01-08T10:24:58
别光靠beforeunload,页面刷新后会丢失状态,最好配合history API或者用useScrollRestoration来统一管理。
Yvonne456
Yvonne456 · 2026-01-08T10:24:58
我遇到的是路由切换时组件重挂载导致的滚动丢失,不是v6的问题,而是没正确使用key或缓存机制。
SickTears
SickTears · 2026-01-08T10:24:58
scrollPosition存sessionStorage容易冲突,建议加个路由标识前缀,比如`scrollPosition_${location.pathname}`。
Yara182
Yara182 · 2026-01-08T10:24:58
其实v6已经提供了useScrollRestoration,直接用它比手动实现更可靠,文档里提得不够清楚,开发时容易忽略