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

React Router Dom路由切换时滚动至顶部的实现问题

问题描述

我使用的是react-router-dom@6.16.0,路由功能正常,但在页面中部点击导航链接跳转时,新页面会从中间位置加载而非顶部。查资料得知react-router-dom提供了ScrollRestoration组件替代传统的useEffect滚动方案,但不清楚如何在createBrowserRouter中使用该组件。

以下是我的App.js代码:

import { RouterProvider, createBrowserRouter } from 'react-router-dom'
import {
  Courses,
  Error,
  Home,
  HomeLayout,
  Login,
  Register,
  Testing,
  Course,
  Contact,
  About,
  FAQ,
  Events,
  EventDetails,
  Library,
  Admin,
} from '@/pages'

const router = createBrowserRouter([
  {
    path: '/',
    element: <HomeLayout />,
    errorElement: <Error />,
    children: [
      {
        index: true,
        element: <Home />,
      },
      {
        path: 'courses',
        element: <Courses />,
      },
      {
        path: 'single-course',
        element: <Course />,
      },
      {
        path: 'testing',
        element: <Testing />,
      },
      {
        path: 'contact',
        element: <Contact />,
      },
      {
        path: 'about-us',
        element: <About />,
      },
      {
        path: 'faq',
        element: <FAQ />,
      },
      {
        path: 'events',
        element: <Events />,
      },
      {
        path: 'event-details',
        element: <EventDetails />,
      },
      {
        path: 'library',
        element: <Library />,
      },
    ],
  },
  {
    path: '/login',
    element: <Login />,
  },
  {
    path: '/register',
    element: <Register />,
  },
  {
    path: '/admin',
    element: <Admin />,
  },
])

const App = () => {
  return <RouterProvider router={router} />
}

export default App
解决方案

ScrollRestoration得放在路由层级里才能监听路由变化,处理滚动恢复。按下面步骤来就行:

1. 先导入组件

在要用的文件里先把ScrollRestoration引进来:

import { ScrollRestoration } from 'react-router-dom'

2. 把组件加到布局或路由元素里

给根布局的子路由加

你的HomeLayout是根路由的容器,所有子页面都嵌套在它里面,直接在HomeLayout里加ScrollRestoration就行,这样所有子页面跳转都会自动滚到顶部:

// HomeLayout.jsx
import { ScrollRestoration, Outlet } from 'react-router-dom'

const HomeLayout = () => {
  return (
    <div>
      {/* 这里放你的导航栏、页头这些内容 */}
      <Outlet />
      {/* 加这行就行 */}
      <ScrollRestoration />
    </div>
  )
}

给独立路由(Login、Register、Admin)加

这些页面没嵌套在HomeLayout里,有两种处理方式:

第一种:整个通用布局

先整个简单的通用布局组件:

// CommonLayout.jsx
import { ScrollRestoration, Outlet } from 'react-router-dom'

const CommonLayout = () => {
  return (
    <div>
      <Outlet />
      <ScrollRestoration />
    </div>
  )
}

然后改路由配置,把这些独立路由套进这个布局:

const router = createBrowserRouter([
  // 根路由原样保留
  {
    path: '/',
    element: <HomeLayout />,
    errorElement: <Error />,
    children: [...],
  },
  {
    path: '/login',
    element: <CommonLayout />,
    children: [{ index: true, element: <Login /> }]
  },
  {
    path: '/register',
    element: <CommonLayout />,
    children: [{ index: true, element: <Register /> }]
  },
  {
    path: '/admin',
    element: <CommonLayout />,
    children: [{ index: true, element: <Admin /> }]
  },
])

第二种:直接在组件里加

比如在Login.jsx里直接加:

import { ScrollRestoration } from 'react-router-dom'

const Login = () => {
  return (
    <div>
      {/* 登录页面的内容 */}
      <ScrollRestoration />
    </div>
  )
}

提醒一下

  • ScrollRestoration默认会处理跳转新页面到顶部,返回时回到之前的滚动位置,和浏览器原生行为一致,不用额外写逻辑。
  • 每个路由层级里只加一次,别重复加,不然会有重复监听的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 04:31:00