← 返回目录

第 8 卷

第 8 / 28 卷日期:

• 实现逻辑:父组件定义回调函数,通过 Props 传递给子组件;子组件触发事件时,调用该回调函

  • 适用场景:子组件向父组件传递用户操作数据(如表单输入值、按钮点击状态)。

• 方式 3:父组件获取子组件实例/DOM:Refs 传递:

• 实现逻辑:父组件通过 useRef(函数组件)或 createRef(类组件)创建 Ref 对象,传递给

子组件;子组件通过 ref 属性接收,父组件可通过 Ref 对象直接访问子组件的实例(类组件)或 DOM 元素(函数组件需用 forwardRef 转发)。

• 适用场景:父组件需要直接操作子组件的 DOM(如获取输入框焦点)或调用子组件的方法(如类

组件的实例方法)。

• 示例(函数组件转发 Ref):

2. 兄弟组件通信

• 方式:通过共同父组件中转:

• 实现逻辑:兄弟组件的通信需借助它们的共同父组件:兄组件通过回调函数将数据传递给父组件,

父组件将数据通过 Props 传递给弟组件。

• 适用场景:兄弟组件之间需要共享数据或交互(如兄组件点击按钮,弟组件展示对应数据),且组

件层级较浅。

• 示例:

3. 跨层级组件通信(祖孙、远亲组件)

• 方式 1:Context API(React 内置):

• 实现逻辑:通过 React.createContext 创建上下文对象,父组件通过 Provider 组件提供

数据,所有子组件(无论层级多深)都可通过 useContext(函数组件)或 static contextType(类组件)订阅并获取上下文数据。

• 适用场景:跨层级组件共享少量全局数据(如用户登录状态、主题配置、语言设置),避免 Props

层层传递(Props Drilling)。

• 示例:

• 方式 2:状态管理库(复杂应用):

• 实现逻辑:使用专门的状态管理库(如 Redux、Zustand、Jotai)管理全局状态,所有组件可通

过库提供的 API(如 Redux 的 useSelector / useDispatch)获取或修改全局状态,实现跨层级通信。

• 适用场景:大型应用、多个跨层级组件需要共享复杂状态(如电商购物车、用户权限),或需要状

态回溯、异步状态管理的场景。

• 方式 1:事件总线(Event Bus):

• 实现逻辑:基于发布-订阅模式(如使用 events 库或自定义事件总线),组件通过「发布事件」

发送数据,其他组件通过「订阅事件」接收数据,无需依赖组件关系。

• 适用场景:非父子、非兄弟的零散组件之间的通信,且不适合使用 Context 或状态管理库的简单场

景。

• 注意事项:需手动管理事件订阅与取消(避免内存泄漏),大型应用中易导致代码逻辑混乱,不推

荐优先使用。

• 方式 2:LocalStorage/SessionStorage(持久化通信):

• 实现逻辑:组件通过 localStorage.setItem 存储数据,其他组件通过

localStorage.getItem 获取数据,利用浏览器本地存储实现跨组件通信。

• 适用场景:需要持久化存储数据的场景(如用户登录信息持久化、页面刷新后保留状态),但注意

数据同步问题(需监听 storage 事件感知数据变化)。

5. 组件通信方式选择总结

组件关系推荐通信方式适用场景
父子组件Props + 回调函数、Refs简单数据传递、父操作子

DOM/方法

兄弟组件共同父组件中转层级较浅的兄弟组件交互
跨层级组件Context API(简单场景)、全局数据共享、避免 Props
状态管理库(复杂场景)层层传递
零散组件(无明确关系)事件总线、LocalStorage简单数据传递、持久化数据

十六、React-Router 的实现原理是什么?它是如何在 React 应用中管理路

由的?

1. React-Router 核心实现原理

React-Router 是基于 React 生态的路由管理库,核心实现原理依赖于浏览器内置的路由 API 和 React 的组件化思想,核心目标是实现“URL 与 UI 组件的映射关系”,让不同 URL 对应不同的页面

组件,同时支持无刷新页面跳转。其核心原理可拆解为 3 点:

• 基于浏览器路由机制(两种模式):React-Router 提供两种路由模式,适配不同场景,底层依赖

• Hash 模式(默认模式):依赖浏览器 URL 中的 Hash(# 后面的部分),通过监听

• History 模式:依赖 HTML5 新增的 History API( pushState、 replaceState 方法和

popstate 事件)。通过 pushState / replaceState 可以修改 URL 且不触发页面刷新,通过监听 popstate 事件感知浏览器前进/后退按钮的操作。该模式 URL 中无 #,更美观,但需

要后端配置(所有路由都指向 index.html,避免刷新 404)。

• 组件化封装路由逻辑:React-Router 将路由相关逻辑封装为可复用的 React 组件(如

<BrowserRouter>、 <Route>、 <Link>),开发者无需直接操作浏览器路由 API,通过组件组合即可实现路由管理。

• 上下文(Context)传递路由状态:React-Router 内部通过 createContext 创建路由上下文

(RouterContext),由最外层的 <BrowserRouter> 或 <HashRouter> 提供路由核心状态(如当前 URL、路由匹配规则、跳转方法等),内部组件(如 <Route>、 <Link>、

useNavigate)通过消费上下文获取路由状态和方法,实现跨组件路由通信。

2. React-Router 在应用中管理路由的核心流程

React-Router 通过“组件组合 + 路由匹配 + 状态同步”三个核心步骤管理路由,具体流程如下:

  1. 1. 初始化路由根容器:在应用入口处,用 <BrowserRouter>(History 模式)或

<HashRouter>(Hash 模式)包裹整个应用组件,该根组件的核心作用是:

  1. 初始化路由模式(绑定对应的浏览器 API 事件,如 hashchange 或 popstate);
  2. 创建并提供路由上下文(RouterContext.Provider),将当前 URL、跳转方法(如 push、

replace)等核心状态传递给内部组件。

  1. 2. 定义路由规则(URL 与组件映射):通过 <Route> 组件定义路由规则,核心属性是 path

(URL 路径)和 element(对应渲染的组件),示例: <Route path="/home"

element={<Home />} />。

  1. 同时可使用 <Routes>(React-Router v6+ 新增,替代旧版 <Switch>)包裹多个

<Route>,实现“排他性匹配”(即只渲染第一个匹配成功的 <Route>,避免多个路由同时匹配)。

  1. 3. 实现页面跳转(无刷新导航):通过 <Link> 组件或编程式导航实现页面跳转,避免传统

<a> 标签跳转导致的页面刷新:

7.<Link to="/about">关于我们</Link>:内部通过调用路由上下文提供的 push 方法,底层调用 pushState(History 模式)或修改 window.location.hash(Hash 模式),实现

无刷新 URL 变更。

全站分卷索引 · 28 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷
  27. 27第 27 卷
  28. 28第 28 卷