Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
T treasure
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 13
    • Issues 13
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • External wiki
    • External wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • FE
  • treasure
  • Issues
  • #179

Closed
Open
Created Aug 22, 2023 by 曹瑞秋@rachelDeveloper

浏览器回退时是否会重新加载相关问题

Q:在传统多页应用(MPA)中页面回退是否会重新加载?

A:在传统MPA中(不做任何处理和优化的情况下),只要是发生路由变化,都会被视为页面跳转,如index.html -> index2.html or index2.html->index.html以及window.histry.back() or window.histry.go(-1)都会出现页面的重新加载,因为现象上看到的就是从页面A到页面B,自然就需要加载对应的页面内容;

Q:在现代单页应用(SPA)中页面回退是否会重新加载?

A:在现代SPA中本身不存在页面的跳转,只是路由变化,所以只要是在当前页面内的路由变化,本质上是不会触发浏览器的重新加载的,window.histry.back() or window.histry.go(-1)也都一样,只是触发了路由变化而已

Q:那为什么在SPA中我返回上一页时会看到页面组件重新加载,并且重新发起请求呢?

A:常见的情况有比如说列表页现在在第4页时,跳转详情,返回后又回到了第一页并在控制台能看到重新发起了页面相关请求,这是因为我们的路由配置原因; 如下代码配置了我们应用各个路由所需要加载的组件,匹配到对应路由时则会渲染对应的组件,所以在路由变化时,就会执行组件卸载/组件加载,故而出现页面内容刷新的情况,但左侧菜单栏、顶部信息栏等不跟随路由变化而变化,所以全局只会加载一次不会出现重复加载的情况

<RouterControl locationTo={location} isOpen={isOpen} routeList={routeList} setDismissLogin={setDismissLogin}>
      <Layout routeList={routeList} isOpen={isOpen || !!matchQuery(location.search, 'source')}>
        <Suspense fallback={<Spin />}>
          <TransitionGroup component={null}>
            <CSSTransition key={location.pathname} classNames='fade' timeout={300}>
              {/* https://juejin.cn/post/6844903922574819342#heading-7 */}
              <Routes location={location}>
                {routeList.map((item) => (
                  <Route key={item.path} path={item.path} element={<item.component location={location} />}></Route>
                ))}
                {/* 匹配找不到的路由 */}
                <Route path='*' element={<NotFound />}></Route>
              </Routes>
            </CSSTransition>
          </TransitionGroup>
        </Suspense>
      </Layout>
    </RouterControl>

Q:那我们要怎么合理的解释这一个情况呢?

A:这就需要结合react-router原理来说了;和react-router相关联的有两个库,分别是react-router-dom & history.js,在开发中我们通常不会直接依赖react-router、histroy.js,而是把所有API、组件从react-router-dom导出使用,它们的关系如下图

Snipaste_2023-08-22_16-35-21

  • react-router 实现了 router 的最核心能力。提供了Router、Route等组件,以及配套方法、hook。
  • react-router-dom 则是 react-router 在浏览器下的更上一层封装。把浏览器 history api 传入Router 并初始化成 BrowserRouter、HashRouter,补充了 Link 这样给浏览器直接用的组件。同时把 react-router 透传导出,减少开发者依赖。
  • history.js 给 browser、hash 两种 history 统一了 api,补充了订阅的能力,最终规范成 react-router 需要的接口供react-router-dom 调用。
    • 核心能够让SPA不刷新就改变浏览器地址的就是通过这个第三方库来实现的
    • 这个库同时劫持了浏览器的前进后退事件,具体如何实现就不在这赘述了,可以自行查阅 github地址
Edited Aug 22, 2023 by 曹瑞秋
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking