← 返回目录

第 9 卷

第 9 / 28 卷日期:

  1. 4. 路由匹配与 UI 渲染:当 URL 发生变化时(如点击 <Link>、浏览器前进/后退),React-

Router 会:

  1. 监听 URL 变化事件( hashchange 或 popstate),更新路由上下文的“当前 URL”状态;
  2. <Routes> 组件遍历内部所有 <Route>,对比 Route.path 与当前 URL,找到匹配成功

的 <Route>;

  1. 渲染匹配成功的 <Route>.element 组件,完成“URL 变化 → UI 更新”的映射。
  2. 5. 路由参数与嵌套路由处理:支持动态路由参数(如 path="/detail/:id"),通过

useParams 钩子获取参数(如 const { id } = useParams());支持嵌套路由(如 <Route path="/user" element={<User>} ><Route path="profile" element=

{<Profile>} /></Route>),通过 <Outlet> 组件渲染子路由对应的组件。

十七、对 Redux 的理解是什么?它主要解决了哪些问题?

1. 对 Redux 的核心理解

Redux 是一款基于“单向数据流”理念的状态管理库(非 React 专属,可配合任意框架使用,常与 React-Redux 结合用于 React 应用),核心作用是集中管理应用中多个组件共享的复杂状态,让状态

变化可预测、可追踪。其核心设计遵循三大原则:

• 单一数据源:整个应用的状态集中存储在一个“状态树”(store)中,避免多个组件分散存储状态

导致的同步问题。

• 状态不可变:状态(state)是只读的,不能直接修改,只能通过触发“动作”(action)生成新的

状态,确保状态变化可追溯。

• 使用纯函数修改状态:通过“减速器”(reducer)函数处理状态更新,reducer 是纯函数(无副

作用、输入相同则输出相同),接收旧状态和 action,返回新状态,避免状态修改逻辑混乱。

简单来说,Redux 的核心思想是“将状态管理从组件内部抽离,交给独立的全局 store 管理,通过规范的流程修改状态”,让组件专注于 UI 渲染,而非状态管理逻辑。

2. Redux 主要解决的问题

Redux 主要解决 React 应用中“状态管理混乱”的问题,尤其是在中大型应用中,具体可分为以下 4 类:

• 解决跨组件状态共享问题:在 React 中,父子组件可通过 Props 传递状态,但跨层级组件(如祖孙

组件)、无直接关系的组件(如兄弟组件)共享状态时,需要通过“Props 层层传递”(即 Props

• 解决状态变化不可预测问题:组件内部通过 setState 直接修改状态时,状态变化逻辑分散在各

变化都有明确的动作描述,且可通过 Redux DevTools 追踪状态变化历史,让状态变化可预测、可调试。

• 解决异步状态管理复杂问题:React 组件中处理异步逻辑(如网络请求)时,异步结果修改状态的

逻辑分散在组件的生命周期或事件回调中,容易导致“异步流程混乱”“多次请求竞态”等问题。

Redux 配合中间件(如 redux-thunk、redux-saga)可将异步逻辑抽离到组件外部,通过规范的方式处理异步动作,让异步状态管理更清晰、可维护。

• 解决组件复用状态逻辑困难问题:多个组件需要复用相同的状态管理逻辑(如用户登录状态、表单

提交逻辑)时,传统方式需通过高阶组件(HOC)或 Render Props 封装,容易导致组件嵌套过深(回调地狱)。Redux 将状态逻辑抽离到 reducer 和 action 中,多个组件可通过订阅 store 或调

用 action 复用相同逻辑,无需嵌套组件。

注意:Redux 并非所有应用都必需,小型应用(状态简单、组件通信少)使用 React 内置的 useState、 useContext 即可满足需求;中大型应用(状态复杂、多组件共享状态多)使用

Redux 才能体现其价值。

十八、Redux 的工作原理及其流程是怎样的?

1. Redux 核心工作原理

Redux 的工作原理基于“单向数据流”和“发布-订阅模式”,核心是通过“store(状态容器)、 action(动作描述)、reducer(状态处理器)”三个核心模块的协同工作,实现状态的集中管理和可

预测更新:

• store:全局唯一的状态容器,存储整个应用的状态树(state),提供 getState()(获取状

态)、 dispatch(action)(触发状态更新)、 subscribe(listener)(订阅状态变化)

三个核心方法。

• action:状态变化的“动作描述”,是修改状态的唯一触发源,必须是纯对象,且必须包含

type 属性(描述动作类型,如 type: 'USER_LOGIN'),可选包含 payload 属性(传递状态更新所需的数据,如 payload: { username: 'admin' })。

• reducer:纯函数,负责处理状态更新逻辑,接收两个参数: prevState(旧状态)和

action(动作描述),根据 action.type 判断需要执行的逻辑,返回新的状态(不能直接修改旧状态)。

核心逻辑:组件通过 dispatch 触发 action,action 被 reducer 接收并处理,reducer 返回新状态更新 store,store 通知所有订阅状态变化的组件,组件重新获取新状态并渲染 UI。

  1. 2. 组件订阅 store 状态:组件通过 store.subscribe(() => {

this.setState(store.getState()) })(类组件)或 React-Redux 的 useSelector 钩子(函数组件)订阅 store 状态,当 store 状态变化时,组件会自动获取新状态并重新渲染。

  1. 3. 组件触发 action:用户点击登录按钮,组件内部调用 store.dispatch(action) 触发状

态更新,其中 action 是描述“登录动作”的对象,示例: const loginAction = { type:

'USER_LOGIN', payload: { username: 'admin' } }。

  1. 4. reducer 处理 action 并返回新状态:store 接收到 action 后,自动调用 reducer 函数,传入当

前旧状态( prevState)和 action:

  1. 5. store 更新状态并通知组件:reducer 返回新状态后,store 会用新状态替换旧状态
  • currentState = newState),然后遍历执行所有通过 subscribe 订阅的监听函数,

通知组件“状态已更新”。

  1. 6. 组件重新渲染:组件接收到 store 的状态更新通知后,通过 store.getState() 或

useSelector 获取新状态,触发组件重新渲染,展示更新后的 UI(如显示用户名、隐藏登录按钮)。

3. 异步场景补充(需中间件)

上述流程是同步场景,若需要处理异步逻辑(如登录前先发送网络请求验证账号密码),则需要在“组件触发 action”和“reducer 处理 action”之间加入 Redux 中间件(如 redux-thunk)。中

间件的作用是“拦截 action”,先执行异步逻辑(如网络请求),待异步完成后,再触发真正的同步 action 交给 reducer 处理,流程变为:组件 dispatch 异步 action → 中间件拦截并执行异步逻辑 →

异步完成后 dispatch 同步 action → reducer 处理同步 action → 更新 store → 组件渲染。

十九、在 Redux 中,异步请求应如何处理?Redux 中间件是什么?如何

编写 Redux 的中间件?

1. Redux 中处理异步请求的方式

Redux 原生(reducer 是纯函数)不支持异步逻辑,处理异步请求(如网络请求)必须借助 Redux 中间件,核心思路是“通过中间件拦截 action,在 action 到达 reducer 之前执行异步逻辑,异步完成后

再触发同步 action 更新状态”。常见的 3 种处理方式:

• 方式 1:使用 redux-thunk(最常用,简单场景):

• 核心原理:允许 dispatch 的 action 是一个“函数”(而非纯对象),这个函数接收 dispatch

和 getState 作为参数,在函数内部执行异步逻辑,异步完成后通过 dispatch 触发同步

全站分卷索引 · 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 卷