You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router:如何返回上一页时恢复滚动位置

解决返回缩略页时定位到上次滚动位置的方案

这问题我之前做图片画廊项目时也碰到过,用户返回时回到顶部的体验确实很差。下面分享两种靠谱的实现思路,根据你的需求和技术栈选就行:

方案一:用 sessionStorage 持久化滚动位置(推荐)

这种方式能保留滚动位置,就算用户刷新页面也不会丢失,体验更友好。核心逻辑是:离开缩略页前保存滚动位置,返回时读取并恢复。

import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

const ThumbnailPage = () => {
  const [scrollPosition, setScrollPosition] = useState(0);

  // 监听滚动事件,实时记录当前位置
  useEffect(() => {
    const handleScroll = () => {
      setScrollPosition(window.scrollY);
    };
    window.addEventListener('scroll', handleScroll);

    // 组件挂载/返回时,恢复滚动位置
    window.scrollTo(0, scrollPosition);

    // 组件卸载前,把位置存到 sessionStorage
    return () => {
      sessionStorage.setItem('thumbnailScrollPos', scrollPosition.toString());
      window.removeEventListener('scroll', handleScroll);
    };
  }, [scrollPosition]);

  // 首次挂载时,读取之前保存的位置
  useEffect(() => {
    const savedPos = sessionStorage.getItem('thumbnailScrollPos');
    if (savedPos) {
      const posNum = parseInt(savedPos, 10);
      setScrollPosition(posNum);
      window.scrollTo(0, posNum);
    }
  }, []);

  return (
    <div className="thumbnail-list">
      {/* 你的缩略图列表 */}
      {images.map(img => (
        <Link key={img.id} to={`/fullscreen/${img.id}`}>
          <img src={img.thumbnail} alt={img.title} />
        </Link>
      ))}
    </div>
  );
};

export default ThumbnailPage;

关键细节:

  • sessionStorage 是会话级存储,关闭浏览器标签后才会清空,刚好匹配这种场景
  • 如果你的缩略页用了虚拟列表(比如 react-window),不要用 window.scrollY,而是通过 ref 获取列表容器的 scrollTop 值

方案二:通过 React Router 的 state 传递滚动位置

如果不需要持久化(比如刷新页面不用保留位置),可以用路由的 state 临时传递滚动位置,适合轻量化场景。

1. 缩略页跳转时传递位置

<Link 
  to={`/fullscreen/${img.id}`}
  // 把当前滚动位置作为路由 state 传递
  state={{ scrollPos: window.scrollY }}
>
  <img src={img.thumbnail} alt={img.title} />
</Link>

2. 全屏页返回时带回位置

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

const FullscreenPage = () => {
  const location = useLocation();

  return (
    <div className="fullscreen-container">
      <img src={currentImage.src} alt={currentImage.title} />
      {/* 返回时把之前的滚动位置再传回去 */}
      <Link 
        to="/thumbnails"
        state={{ scrollPos: location.state?.scrollPos || 0 }}
      >
        ← 返回缩略页
      </Link>
    </div>
  );
};

3. 缩略页接收并恢复位置

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

const ThumbnailPage = () => {
  const location = useLocation();

  useEffect(() => {
    const scrollPos = location.state?.scrollPos;
    if (scrollPos !== undefined) {
      window.scrollTo(0, scrollPos);
      // 可选:清除 state,避免下次刷新页面还带着旧值
      location.state = null;
    }
  }, [location]);

  // ... 其他代码
};

额外注意事项

  • 如果你的缩略页是嵌套在其他布局组件里(比如有固定导航栏),计算滚动位置时要考虑导航栏高度,避免被遮挡
  • 类组件的实现思路一致,把 useEffect 换成 componentDidMount、componentWillUnmount 即可

内容的提问来源于stack exchange,提问作者yN.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:58:40