细读 React | React Router 路由切换原理

[复制链接]
发表于 2025-11-1 12:30:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
                  2022 北京冬奥会开幕式          此前不绝在迷惑,显着 pushState()、replaceState() 不触发 popstate 事故,可为什么 React Router 还能挂载对应路由的组件呢?
   翻了一下 history.js 源码,终于知道缘故起因了。
   源码

   假设项目路由计划如下:
  
  1. import { render } from 'react-dom'
  2. import { BrowserRouter, Routes, Route } from 'react-router-dom'
  3. import { Mine, About } from './routes'
  4. import App from './App'
  5. const rootElement = document.getElementById('root')
  6. render(
  7.   <BrowserRouter>
  8.     <Routes>
  9.       <Route path="/" exact element={<App />} />
  10.       <Route path="/mine" element={<Mine />} />
  11.       <Route path="/about" element={<About />} />
  12.     </Routes>
  13.   </BrowserRouter>,
  14.   rootElement
  15. )
复制代码
  然后我们看下 <BrowserRouter /> 的源码(react-router-dom/modules/BrowserRouter.js),以下省略了一部门无关代码:
  
  1. import React from 'react'
  2. import { Router } from 'react-router'
  3. import { createBrowserHistory as createHistory } from 'history'
  4. /**
  5. * The public API for a <Router> that uses HTML5 history.
  6. */
  7. class BrowserRouter extends React.Component {
  8.   // 构建 history 对象
  9.   history = createHistory(this.props)
  10.   render() {
  11.     // 将 history 对象等传入 <Router /> 组件
  12.     return <Router history={this.history} children={this.props.children} />
  13.   }
  14. }
  15. // ...
  16. export default BrowserRouter
复制代码
  接着我们继续看下 <Router /> 组件的源码(react-router/modules/Router.js),如下:
  
  1. import React from 'react'
  2. import HistoryContext from './HistoryContext.js'
  3. import RouterContext from './RouterContext.js'
  4. /**
  5. * The public API for putting history on context.
  6. */
  7. class Router extends React.Component {
  8.   static computeRootMatch(pathname) {
  9.     return { path: '/', url: '/', params: {}, isExact: pathname === '/' }
  10.   }
  11.   constructor(props) {
  12.     super(props)
  13.     this.state = {
  14.       location: props.history.location
  15.     }
  16.    
  17.     // 关键点:
  18.     // 当触发 popstate 事件、
  19.     // 或主动调用 props.history.push()、props.history.replace() 方法时,
  20.     // 都会执行 history 对象的 listen 方法,使得执行 setState 强制更新当前组件
  21.     this.unlisten = props.history.listen(location => {
  22.       this.setState({ location })
  23.     })
  24.   }
  25.   componentWillUnmount() {
  26.     // 组件卸载时,解除监听
  27.     if
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表