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

React路由切换时页面滚动至顶部问题求助

React Router v6 页面切换时无法滚动到顶部的解决方案

问题

使用React 18.2.0和react-router-dom v6开发时,在首页向下滚动后导航至其他页面(如条款与条件页),页面切换时窗口未自动滚动到顶部,而是停留在之前的scrollY位置。尝试过ScrollToTop、ScrollRestoration组件,但问题未解决。

现有App.js代码

import { useState } from "react";
import { MemoryRouter as Router, Routes, Route } from "react-router-dom";
import { createTheme, ThemeProvider } from "@mui/material";
import { Home, Support, About, ContactUs, Terms, Calculator } from "./views";
import './styles/global.css';
import themes from "./utils/ThemeUtils";
import Layout from "./components/Layout";
import FullLayout from "./components/FullLayout";

function App() {
    const [theme, setTheme] = useState(localStorage.getItem("theme") || "light");
    const lightTheme = createTheme(themes.lightTheme);
    const darkTheme = createTheme(themes.darkTheme);

    return (
        <ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
            <Router >
                <Routes>
                    <Route element={<Layout setTheme={setTheme} theme={theme} />}>
                        <Route path="/" element={<Home />} />
                        <Route path="/about" element={<About />} />
                        <Route path="/terms" element={<Terms />} />
                        <Route path="/contact" element={<ContactUs />} />
                        <Route path="/support" element={<Support />} />
                    </Route>
                    <Route element={<FullLayout setTheme={setTheme} theme={theme} />}>
                        <Route path="/calculate" element={<Calculator />} />
                    </Route>
                </Routes>
            </Router>
        </ThemeProvider>
    );
}

export default App;

解决方案

方法1:自定义ScrollToTop组件(最可靠)

由于MemoryRouter默认不处理路由切换时的滚动行为,需要监听路由变化并手动触发滚动到顶部。创建如下组件:

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

function ScrollToTop() {
  const { pathname } = useLocation();

  useEffect(() => {
    // 滚动到窗口顶部,可选smooth实现平滑滚动
    window.scrollTo({
      top: 0,
      behavior: 'smooth'
    });
  }, [pathname]);

  return null;
}

然后在App.js的Router内部、Routes之前引入该组件:

// ...其他导入
import ScrollToTop from './components/ScrollToTop'; // 替换为你的组件路径

function App() {
  // ...原有逻辑

  return (
    <ThemeProvider theme={theme === "light" ? lightTheme : darkTheme}>
      <Router >
        <ScrollToTop /> {/* 添加在这里 */}
        <Routes>
          {/* 原有路由配置 */}
        </Routes>
      </Router>
    </ThemeProvider>
  );
}

方法2:排查ScrollRestoration的正确用法

ScrollRestoration组件主要用于恢复之前页面的滚动位置,而非切换时强制回到顶部。如果要使用它,需确保放在Router内部,但如果你的需求是每次切换都回到顶部,方法1更直接。若坚持使用,可结合useEffect重置滚动:

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

function CustomScrollRestoration() {
  const { pathname } = useLocation();

  useEffect(() => {
    window.scrollTo(0, 0);
  }, [pathname]);

  return <ScrollRestoration />;
}

同样将该组件放在Router内部使用。

方法3:检查布局组件的滚动容器

如果你的Layout或FullLayout组件中使用了固定定位、overflow: auto的容器(滚动发生在容器内而非window),则需要针对该容器处理滚动:

// ScrollToTop组件修改为针对容器滚动
import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';

function ScrollToTop() {
  const { pathname } = useLocation();
  const scrollContainerRef = useRef(null);

  useEffect(() => {
    // 假设滚动容器是Layout中的某个元素,通过ref获取
    if (scrollContainerRef.current) {
      scrollContainerRef.current.scrollTop = 0;
    } else {
      window.scrollTo(0, 0);
    }
  }, [pathname]);

  // 需要在Layout组件中将滚动容器的ref传递过来,或者通过document.querySelector获取
  return null;
}

此时需确保布局组件中的滚动容器能被正确获取到。

内容的提问来源于stack exchange,提问作者Abdalrahman Al-Ashgr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:47:20