React 核心知识点

3 阅读24分钟

React 从16到19版本的演进,见证了前端框架从同步渲染走向并发渲染,再到服务端组件架构的完整历程。针对2026年的React面试,我整理了这份全面的题库,按照核心原理Hooks深度版本特性性能优化生态集成五个维度进行梳理,每道题均包含详细的解析和版本标注。


一、React核心原理与设计思想

1. 请解释React中的虚拟DOM及其作用

难度:考察点: 基础原理、设计理念

解析: 虚拟DOM(Virtual DOM)是 React 的核心设计之一,它本质上是一个轻量级的 JavaScript 对象树,是真实 DOM 的抽象表示。

核心价值并非“快”,而是“跨平台”与“批量更新”

  1. 性能保障:虽然直接操作 DOM 最快,但手动优化成本高。虚拟 DOM 通过 diff 算法找出最小差异,再批量更新,确保了跨平台的最低性能下限。
  2. 简化开发:开发者只需操作状态,React 负责将虚拟 DOM 映射到真实 DOM,极大提高了开发效率。
  3. 跨平台能力:由于虚拟 DOM 是抽象结构,React 可以将其渲染为 DOM(Web)、Native 组件(移动端)或 Canvas 等。

工作原理:当组件状态变化时,React会创建新的虚拟DOM树,与旧树进行diff比较,计算出最小更新范围,最后批量更新真实DOM。

2. 什么是React Fiber?它解决了什么问题?

难度: ⭐⭐⭐ 考察点: React 16 核心架构、渲染机制

解析: Fiber 是 React 16 中全新的协调(Reconciliation)引擎,是对核心算法的重写。

解决的问题: 在 React 16 之前,协调过程是同步递归的,一旦开始无法中断。当组件树庞大时,会长时间占用主线程,导致用户输入或动画卡顿。

Fiber 的核心设计

  1. 可中断的渲染:将渲染工作拆分成多个小单元(Fiber 节点),基于链表遍历,每执行完一个单元,将控制权交还给浏览器。
  2. 任务优先级调度:区分高优(如用户输入、动画)和低优(如数据请求)更新,优先处理高优任务。
  3. 双缓存机制:在内存中维护两棵树——current tree(当前屏幕显示)和 workInProgress tree(正在构建)。构建完成后直接切换指针,保证视图的一致性。
  4. 并发模式的基础:Fiber 架构为 React 18 的并发渲染奠定了技术基础。

3. React 的 Diff 算法是如何工作的?为什么 key 很重要?

难度: ⭐⭐ 考察点: 协调机制、性能优化

解析: Diff 算法基于三个策略,将复杂度降至 O(n):

  1. 分层比较:只对同级节点进行比较。如果节点跨层级移动,React 会视为删除并重建,而非移动。
  2. 类型比较:如果节点类型不同(如从 <div><span>),直接删除旧节点及其子树,创建新树。
  3. 列表比较(key 的作用):在比较子节点列表时,通过 key 属性判断节点是否只是位置移动。

为什么不能用索引作为 key?:当在列表头部插入新元素时,所有后续元素的索引都会变化,React 会误认为所有节点都发生了变化,导致性能下降甚至状态错乱。应使用唯一且稳定的标识符(如数据库 ID)。

4. 为什么 setState 有时是异步的,有时又是同步的?

难度: ⭐⭐ 考察点: 状态更新机制、批处理

解析: setState 的表现取决于执行上下文:

  • 异步(批处理):在 React 合成事件生命周期函数 中,setState 是异步的。React 会将多个更新合并(batch)为一次重新渲染,以避免不必要的性能损耗。
  • 同步:在 setTimeout原生事件(如 addEventListener)或 Promise 回调中,setState 是同步执行的,会立即更新并渲染。

React 18 变化:即使是在 setTimeout 或 Promise 中,自动批处理 功能也会将它们合并为一次渲染。如果希望强制同步更新,可以使用 flushSync

5. React 中的合成事件(SyntheticEvent)是什么?

难度: ⭐⭐ 考察点: 事件系统、跨浏览器兼容

解析: 合成事件是浏览器原生事件系统的跨浏览器包装器,旨在确保不同浏览器之间的行为和性能一致。

设计动机

  1. 抹平浏览器差异:无需再处理浏览器事件机制方面的兼容问题。
  2. 中心化管控:React 把握了事件机制的主动权,实现了对所有事件的中心化管控。
  3. 性能优化:通过事件委托减少内存开销。

事件绑定位置的变化

  • React 16:事件绑定在 document 上。
  • React 17+:事件绑定在 React 渲染的根容器(如 root)上,便于多版本 React 共存。

6. React 中元素(Element)和组件(Component)有什么区别?

难度:考察点: 基础概念辨析

解析:

  • 元素(Element):是一个普通对象,描述组件实例或 DOM 节点及其所需的属性。元素是 React 应用程序的最小构建块,通常使用 JSX 创建。

    const element = <h1>Hello</h1>; // 编译后返回一个对象
    
  • 组件(Component):是可重用的 UI 部分,可以由一个或多个元素组成。组件可以是函数组件或类组件,封装了渲染和行为的逻辑,可以接受 props 并维护内部状态。

7. 什么是 JSX?它是如何工作的?

难度:考察点: 语法糖、编译原理

解析: JSX 是 JavaScript 的语法扩展,允许在 JavaScript 中编写类似 HTML 的标记。

工作原理

  • JSX 在构建时会被编译工具(如 Babel)转换为 React.createElement() 调用。
  • 例如,<h1 className="greeting">Hello</h1> 被编译为 React.createElement('h1', { className: 'greeting' }, 'Hello')
  • 这些 createElement 调用返回虚拟 DOM 对象,最终由 React 渲染为真实 DOM。

为什么自定义组件首字母要大写?:如果组件首字母为小写,会被当成字符串(HTML 标签)传递;首字母大写则当成变量(自定义组件)传递。

8. 为什么 React 组件必须只有一个根元素?

难度: ⭐⭐ 考察点: 虚拟 DOM 结构

解析: React 组件必须只有一个根元素的原因:

  1. 函数返回值限制:React 组件最终编译为 render 函数,函数的返回值只能是 1 个,如果不用单独的根节点包裹,就会并列返回多个值,这在 JavaScript 中是不允许的。
  2. 虚拟 DOM 树结构:React 的虚拟 DOM 是一个树状结构,树的根节点只能是 1 个。如果有多个根节点,无法确定是在哪棵树上进行更新。

如何返回多个组件?

  • 使用 React.Fragment(或 <></> 简写):将元素列表分组,不会创建额外节点。
  • 使用 数组返回:直接返回元素数组(需要 key)。

二、React Hooks 深度剖析

9. 为什么不能在循环、条件或嵌套函数中调用 Hooks?

难度: ⭐⭐ 考察点: Hooks 设计原理、调用顺序

解析: Hooks 的底层依赖调用顺序来维护状态。在组件首次渲染时,React 会按照 Hook 的调用顺序将其存储在一个链表中。每次重新渲染时,React 按照相同的顺序读取这些 Hook。

如果在循环或条件中调用 Hook,顺序可能会发生变化(如某个条件不满足导致 Hook 未被执行),React 就无法将当前的 Hook 与之前的对应起来,导致状态错乱或 Bug。

10. useEffect 的依赖数组如何正确使用?

难度: ⭐⭐ 考察点: 副作用管理、闭包陷阱

解析: useEffect 的依赖数组常见错误及正确做法:

常见错误

// ❌ 错误:依赖数组写得不精确
useEffect(() => {
  // 这里用了 data.id
}, [data]); // 应该写成 [data.id]

正确做法

  • 把 effect 中用到的所有外部变量都放进依赖数组。
  • 如果某些依赖不想触发更新,可以使用 useRef 保存。
  • 空依赖 [] 表示只在挂载时执行(相当于 componentDidMount)。
  • 返回清理函数用于卸载时执行(相当于 componentWillUnmount)。

11. useCallback 和 useMemo 有什么区别?

难度: ⭐⭐ 考察点: 性能优化、记忆化

解析: 这两个 Hook 的区别就像"咖啡和茶——看起来像但完全不一样":

特性useCallbackuseMemo
返回值记忆化的函数记忆化的
适用场景函数作为 props 传递时复杂计算结果的缓存
典型用例避免子组件不必要的重新渲染过滤/排序大数据量列表
// useCallback:返回记忆化的回调函数
const memoizedCallback = useCallback(() => { doSomething(a, b); }, [a, b]);

// useMemo:返回记忆化的计算值
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

12. useRef 的作用是什么?如何实现保存上一次的值?

难度: ⭐⭐ 考察点: 引用、可变值

解析: useRef 返回一个可变的 ref 对象,其 .current 属性初始化为传入的参数。返回的对象将在组件的整个生命周期内持续存在。

主要用途

  1. 直接访问和交互 DOM 元素(如表单输入聚焦)。
  2. 存储任何可变值,这些值在更新时不会导致重新渲染,例如计时器 ID、上一次的值等。

实现保存上一次的值(自定义 Hook usePrevious

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}
// 使用:const prevCount = usePrevious(count);

13. useEffect 与 useLayoutEffect 的区别是什么?

难度: ⭐⭐ 考察点: 副作用执行时机

解析:

  • useEffect异步执行。在浏览器完成布局与绘制之后运行。不会阻塞视觉更新,适用于大多数副作用(如数据获取、事件绑定)。
  • useLayoutEffect同步执行。在 DOM 变更后、浏览器绘制之前运行。如果有读取或修改 DOM 布局(如测量元素宽高)并立即需要反映到 UI 上的操作,应使用 useLayoutEffect,以避免出现闪烁。

14. 如何跟踪函数组件的卸载?

难度: ⭐⭐ 考察点: 副作用清理

解析:useEffect 中返回一个清理函数(cleanup function)。当组件卸载时,React 会执行这个清理函数。这用于取消网络请求、清理订阅或清除定时器,防止内存泄漏。

useEffect(() => {
  const subscription = props.source.subscribe();
  return () => {
    // 清理订阅
    subscription.unsubscribe();
  };
}, [props.source]);

15. 什么是自定义 Hook?如何编写?

难度: ⭐⭐ 考察点: 逻辑复用、抽象能力

解析: 自定义 Hook 是一个函数,其名称以 "use" 开头,函数内部可以调用其他的 Hook。它用于将组件逻辑提取到可重用的函数中。

编写示例(表单校验 Hook):

function useFormValidation(initialState, validate) {
  const [values, setValues] = useState(initialState);
  const [errors, setErrors] = useState({});

  const handleChange = (e) => {
    const { name, value } = e.target;
    setValues({ ...values, [name]: value });
    if (validate) {
      const validationErrors = validate({ [name]: value });
      setErrors({ ...errors, ...validationErrors });
    }
  };

  return { values, errors, handleChange };
}

三、React 16-19 版本特性演进

16. React 16 的主要更新是什么?

难度:考察点: 版本历史、Fiber

解析: React 16(2017年发布)是Fiber 架构开始的标志性版本。

  • Fiber 架构重写:用 Fiber 节点树取代原来的 Stack Reconciler,支持任务分片,允许中断和恢复渲染。
  • 错误边界(Error Boundaries):引入 componentDidCatch 生命周期,可以捕获子组件树的渲染错误,防止整个应用崩溃。
  • 新渲染能力:支持返回数组和字符串、Portals(传送门)。
  • 性能优化:更快的协调过程,更小的核心库。

17. React 16.8 引入的 Hooks 解决了什么问题?

难度: ⭐⭐ 考察点: Hooks 设计动机

解析: React 16.8 引入 Hooks,让函数式组件更加灵活。Hooks 之前,React 存在很多问题:

  1. 在组件间复用状态逻辑很难:需要高阶组件或 render props,导致嵌套过深。
  2. 复杂组件变得难以理解:生命周期中混杂不相关逻辑。
  3. class 组件的 this 指向问题:需要手动绑定。
  4. 难以记忆的生命周期:开发者容易用错。

Hooks 很好地解决了上述问题,提供了 useStateuseEffectuseContext 等方法。

18. React 17 作为"过渡版本"带来了哪些改变?

难度:考察点: 对渐进式升级的理解

解析: React 17(2020年发布)官方称为"No New Features"版本,主要致力于渐进式升级兼容性

  1. 事件委托重构:事件绑定从 document 下移至 React 应用的根容器。这使得在同一个页面中多版本 React 共存(如微前端)成为可能,避免了冲突。
  2. 移除事件池:旧版中合成事件对象会被复用(需调用 e.persist()),新版移除了复用机制,使得异步访问事件对象更安全。
  3. 新的 JSX 转换:引入 react/jsx-runtime,编译 JSX 时不再需要显式 import React,减少了打包体积。

19. React 18 的核心新特性是什么?

难度: ⭐⭐ 考察点: 并发模式、渲染优化

解析: React 18(2022年发布)的核心是并发渲染(Concurrent Rendering)

  1. 并发渲染:渲染是可中断的、可恢复的和可优先级的。通过 createRoot API 开启。
  2. 自动批处理:在 React 18 之前,批处理只在事件处理函数中生效。现在,在 Promise、setTimeout 等异步代码中的多个 setState 也会自动合并,减少渲染次数。
  3. 新 HooksuseTransition(标记非紧急更新)、useDeferredValue(延迟更新)、useId(生成唯一 ID,解决 SSR 水合不一致)、useSyncExternalStore(解决外部数据撕裂问题)。
  4. Suspense 的 SSR 支持:支持流式服务端渲染,可以使用 renderToPipeableStream 将 HTML 分段发送给客户端。
  5. 新 Root API:废弃 ReactDOM.render,改用 ReactDOM.createRoot 来启用并发特性。

20. React 18 的并发渲染与传统渲染有何不同?

难度: ⭐⭐⭐ 考察点: 并发模式原理

解析: 并发渲染允许 React 在渲染时根据任务优先级中断和恢复工作,而不是一次性完成所有渲染。

特性React 17 及以下React 18(并发模式)
渲染方式同步,不可中断异步,可中断
优先级调度有,可区分紧急/非紧急更新
用户体验复杂渲染可能卡顿保持响应,优先处理用户输入
技术基础递归遍历Fiber + 时间切片

关键机制

  • 渲染阶段(可中断):React 确定 UI 应该是什么样子,构建组件树。这个阶段可以暂停、恢复或丢弃。
  • 提交阶段(不可中断):React 将变更应用到 DOM,执行副作用。这个阶段必须一次性完成。

21. React 19 带来了哪些颠覆性的变化?

难度: ⭐⭐⭐ 考察点: 最新技术趋势、Server Components

解析: React 19(2024年底发布)的重点在于简化异步操作服务端架构

  1. Actions API(Server Actions):将服务端交互提升为"一等公民"。可以直接在 <form action={serverAction}> 中传递异步函数,React 会自动管理 pending 状态、错误处理和乐观更新。
  2. 新 Hooks
    • useOptimistic:用于实现乐观更新。在服务器响应前,先立即在 UI 上展示预期结果。
    • useActionState(原 useFormState):简化表单提交的状态管理,返回状态和加载标识。
    • useFormStatus:允许子组件(如按钮)读取父级表单的提交状态。
  3. React Compiler:自动进行记忆化(Memoization)优化。开发者无需再手动使用 useMemouseCallback,编译器会在构建时自动分析并缓存稳定值。
  4. React Server Components(RSC):服务端组件正式稳定。组件可以选择在服务器上运行(零打包体积),直接访问数据库,同时与客户端组件无缝组合。
  5. 文档元数据支持:可以直接在组件中渲染 <title><meta> 等标签,React 会自动将其提升到 <head> 中。
  6. ref 传递简化:函数组件可以直接接收 ref 作为 props,无需 forwardRef

22. 什么是 React Server Components(RSC)?它和客户端组件有何不同?

难度: ⭐⭐⭐ 考察点: 下一代 React 架构

解析: React Server Components 是一种只在服务器上运行永远不会发送给客户端的组件。

特性Server ComponentsClient Components
执行环境服务器浏览器(客户端)
打包体积(依赖库也无需下载)正常,包含 JS 逻辑
能力可直接访问数据库/文件系统可使用 State、Effect、事件监听
交互性无交互(不能使用 onClick有完整交互性
指令默认(或 "use server" 函数)需要在文件顶部标记 "use client"

核心价值

  • 零包大小:RSC 的代码(包括大型依赖)永远不会发送给客户端。
  • 直接后端访问:可以安全地直接访问数据库和内部服务。
  • 无缝组合:RSC 可以导入和渲染客户端组件,但反之则不行。

23. React 19 的 React Compiler 是什么?有什么意义?

难度: ⭐⭐⭐ 考察点: 编译时优化

解析: React Compiler(原 "React Forget")是一个新的自动编译器,旨在从根本上解决 React 中不必要的重新渲染问题。

工作原理

  • 编译器深度分析组件代码,仅在真正有益的地方应用记忆化。
  • 确保组件仅在 UI 的语义含义实际发生变化时重新渲染。

意义

  • 自动化优化:无需手动使用 useMemouseCallbackReact.memo
  • 减少样板代码:开发者可以编写更干净、更标准的 JavaScript。
  • 消除性能 bug:不再需要担心依赖数组写错或遗漏。

24. React 19 的 Actions API 如何简化表单处理?

难度: ⭐⭐⭐ 考察点: 服务端交互、渐进增强

解析: Actions API 是 React 19 处理数据变更(特别是表单提交)的一等公民特性。

核心特性

  1. 原生表单集成:异步函数可以直接传递给 <form>action 属性。
  2. 渐进增强:即使 JavaScript 未加载,表单也能正常提交。
  3. 内置状态管理:结合 useActionState 等 Hook,自动处理 pending、成功、错误状态。
  4. 服务端执行:通过 "use server" 指令,函数可以在服务器上安全执行。

示例

'use client'
import { useActionState } from 'react'

async function createTodoAction(formData) {
  "use server" // 标记为服务端函数
  const title = formData.get("title")
  // 保存到数据库
}

export default function TodoForm() {
  const [state, formAction] = useActionState(createTodoAction)
  return <form action={formAction}>...</form>
}

四、性能优化与工程实践

25. 如何避免 React 组件不必要的重新渲染?

难度: ⭐⭐ 考察点: 性能优化策略

解析:

  • 类组件
    • 继承 React.PureComponent(自动浅比较 props 和 state)。
    • 手动实现 shouldComponentUpdate 生命周期。
  • 函数组件
    • 使用 React.memo 包裹组件(默认浅比较,可自定义比较函数)。
    • 使用 useMemo 缓存计算结果,使用 useCallback 缓存函数引用,避免子组件因父组件重新渲染而接收新 props。
  • 架构优化
    • 合理拆分 State,将不相关的状态分离,避免局部变化导致整个大组件重绘。
    • 使用 React.lazy<Suspense> 实现组件懒加载和代码分割。
    • 列表渲染使用稳定且唯一的 key

注意React.memo 不要滥用,只在组件 props 经常变化但渲染结果相同,或组件渲染开销较大时使用。

26. 如何处理大型列表的渲染性能问题?

难度: ⭐⭐ 考察点: 虚拟化、窗口化

解析: 对于渲染大型列表(如 1w+ 条数据),应使用**虚拟化(Virtualization)窗口化(Windowing)**技术。这些库(如 react-windowreact-virtualized)仅渲染视口中可见的项目,显著减少了 DOM 节点的数量,并提高了渲染性能和内存使用率。

真实案例:某商品列表页用 react-window 把渲染时间从 5 秒降到 200ms,用户留存率直接提升 30%。

27. React.memo 的正确使用姿势是什么?

难度: ⭐⭐ 考察点: 记忆化组件

解析: 黄金法则:只在以下情况使用 React.memo

  • 组件 props 经常变化但渲染结果相同。
  • 组件渲染开销较大(比如复杂图表)。
  • 作为 PureComponent 的函数组件版。

错误案例

// ❌ 错误!内联函数会导致每次都是新 props
const MemoComp = React.memo(({ onClick }) => { ... });
<MemoComp onClick={() => {}} />

28. 如何在 React 中实现懒加载?

难度: ⭐⭐ 考察点: 代码分割、Suspense

解析: 结合 React.lazySuspenseErrorBoundary 实现安全的懒加载:

const LazyComponent = React.lazy(() => import('./Component'));

function App() {
  return (
    <ErrorBoundary> {/* 捕获加载失败错误 */}
      <Suspense fallback={<Spinner />}> {/* 加载中显示 */}
        <LazyComponent />
      </Suspense>
    </ErrorBoundary>
  );
}

29. 你在项目中如何使用 Error Boundaries?

难度:考察点: 错误处理机制

解析: Error Boundaries 是 React 16 引入的类组件,用于捕获其子组件树中 JavaScript 错误,防止整个应用崩溃,并展示降级 UI。

  • 实现:通过实现 static getDerivedStateFromError()componentDidCatch() 生命周期。
  • 注意:Error Boundaries 无法捕获事件处理、异步代码、服务端渲染及自身抛出的错误。对于函数组件,目前没有直接替代品,但可以利用第三方库或将其作为高阶组件包裹类组件来复用。

30. 状态更新的并发问题:快速点击时点赞数不准确的根本原因是什么?如何解决?

难度: ⭐⭐⭐ 考察点: 闭包、函数式更新、并发状态

解析: 这是 React 面试中的经典实战问题。

根本原因:当快速多次点击时,多个 setLikes(likes + 1) 调用基于了相同的旧状态值。由于 React 的状态更新可能是异步的或批处理的,每次点击时 likes 的值还没有来得及更新,导致多次更新使用了同一个基数,因此计数不准确。本质上是一个闭包问题——每次渲染的 handleClick 函数捕获了该次渲染时的 likes 值。

解决方案:使用函数式更新,即传入一个函数,该函数接收前一个状态作为参数,返回新状态。

// ✅ 正确方式
const handleLike = () => {
  setLikes(prevLikes => prevLikes + 1);
};

这样,React 会保证每次更新都基于最新的状态值,即使多次更新被合并,也能正确累加。

31. 受控组件和非受控组件有什么区别?

难度:考察点: 表单处理

解析:

  • 受控组件:表单数据由 React 组件的 state 管理。组件接收当前值并通过 props 更新,当值改变时触发回调函数。父组件完全控制该组件的值。

    const [value, setValue] = useState('');
    <input value={value} onChange={(e) => setValue(e.target.value)} />
    
  • 非受控组件:表单数据由 DOM 自身管理。可以使用 ref 从 DOM 中获取表单值。

    const inputRef = useRef(null);
    <input ref={inputRef} />
    // 需要时通过 inputRef.current.value 获取值
    

32. React 中的状态提升(Lifting State Up)是什么?

难度:考察点: 状态共享、组件通信

解析: "状态提升"涉及将共享状态移动到最近的共同祖先组件中。这可以集中状态管理,简化数据流,并确保所有需要该状态的组件都能访问单一事实来源,从而使调试更加容易。当多个组件需要反映相同的变化时,应该将共享状态提升到它们最近的共同父组件中。

33. Context API 和全局状态管理库(如 Redux、Zustand)如何选择?

难度: ⭐⭐ 考察点: 状态管理选型

解析:

  • Context API + useReducer:对于中小型应用程序,或共享不频繁更新的全局数据(如主题、用户认证、区域设置),通常已足够。
  • 专用的全局状态管理库(Redux、Zustand、MobX):对于具有复杂状态交互、频繁更新、需要中间件支持(如异步请求)、或需要集中式调试工具的大型应用程序,它们可以提供更好的可伸缩性、可预测性和可维护性。

Redux 实现了 Flux 模式(单向数据流),MobX 实现了观察者模式(发布-订阅)。

34. React Router 中 Switch 的作用是什么?

难度:考察点: 路由匹配

解析: <Switch> 通常被用来包裹 <Route>,用于渲染与路径匹配的第一个子 <Route><Redirect>

不加 <Switch> 的问题:当 URL 的 path 为 "/login" 时,<Route path="/" /><Route path="/login" /> 都会被匹配,页面会同时显示两个组件。使用 <Switch> 可以做到只显示第一个匹配的组件,结合 exact 属性实现精确匹配。


五、React 生态与工程化

35. 什么是 Redux Thunk?它有什么作用?

难度: ⭐⭐ 考察点: 中间件、异步处理

解析: Redux thunk 是一个允许你编写返回一个函数而不是一个 action 的 actions creators 的中间件。如果满足某个条件,thunk 则可以用来延迟 action 的派发(dispatch),这可以处理异步 action 的派发(dispatch)。

作用:处理 Redux 中的异步操作,如 API 请求。

36. Create React App 是什么?有什么作用?

难度:考察点: 工程化工具

解析: Create React App 是 Facebook 开发的工具,为创建 React 应用程序提供简化的设置。它设置了开发环境,包括配置 Webpack 和 Babel,提供用于实时重新加载的开发服务器。

优势:开发者可以快速开始 React 开发,而无需处理从头配置新项目的复杂性。

37. React 的 Strict Mode 有什么用?

难度: ⭐⭐ 考察点: 开发辅助

解析: <StrictMode /> 是一个帮助开发者在开发过程中识别潜在问题的 React 组件。启用后,它会执行额外的检查并将警告记录到开发控制台。

主要功能

  • 识别不安全的生命周期。
  • 关于遗留字符串 ref API 使用的警告。
  • 检测意外的副作用(通过双重调用渲染)。
  • 检测遗留 context API。

注意:严格模式仅在开发模式下运行,不会影响生产构建。

38. 如何选择使用 React 还是其他框架(如 Angular)?

难度: ⭐⭐ 考察点: 技术选型、框架对比

解析: React 和 Angular 的核心区别在于库 vs 框架

特性ReactAngular
类型JavaScript 库完整的前端框架
架构灵活,可自由选择配套工具内置完整解决方案(状态管理、路由等)
学习曲线相对平缓,但需要选择生态工具较陡峭,但提供一体化方案
适用场景灵活多变、需要精细控制的项目大型企业级应用,需要一致性和规范

React 适合需要灵活性和逐步采用的项目;Angular 适合需要完整、一体化框架的大型项目。

39. 现代 React 应用的工具链是怎样的?

难度: ⭐⭐ 考察点: 工程化理解

解析: 现代 React 工具链旨在将开发者友好的源代码转换为高度优化的生产输出。典型步骤包括:

  1. 代码规范检查:ESLint 强制执行代码质量。
  2. 依赖解析和打包:使用 Webpack、Vite 等工具解析依赖并打包。
  3. 转译:使用 Babel、SWC 或 esbuild 将现代 JavaScript 和 JSX 转换为广泛兼容的代码。
  4. 资源处理:处理 CSS、图片等资源。
  5. 压缩优化:减小代码体积以提高加载性能。
  6. Source Map:将优化后的输出链接回原始源代码以支持调试。

如今,大多数团队依赖更高层次的工具,如 Next.js、Remix 或基于 Vite 的设置,它们将转译、打包、优化和默认配置整合到一个连贯的流水线中。

40. 你对 React 未来发展方向有什么看法?

难度: ⭐⭐⭐ 考察点: 技术视野、学习能力

解析: React 未来发展的几个方向:

  1. 服务端组件成为主流:RSC 将改变应用架构,更多逻辑移到服务器,减少客户端包体积。
  2. 编译器优化普及:React Compiler 将使手动记忆化成为历史,开发者可以专注于业务逻辑。
  3. 并发特性深度集成useTransitionuseDeferredValue 等并发特性将成为日常开发的标准工具。
  4. 表单处理简化:Actions API 将大幅简化表单交互,实现渐进增强。
  5. 元框架进一步整合:Next.js、Remix 等框架将深度整合 React 新特性,提供更完善的全栈开发体验。

总结与备考建议

这份题库涵盖了从 React 基础原理到最新版本特性的全部内容。针对 2026 年的面试,建议重点关注:

  1. React 19 的新特性:Actions API、Server Components、React Compiler 是当前热点。
  2. 并发渲染原理:理解可中断渲染、优先级调度对用户体验的提升。
  3. 性能优化实战:能够结合具体场景说明优化方案。
  4. 工程实践能力:能够展示技术选型和项目经验中的决策过程。

面试中,"别死记硬背答案",现在的面试官更看重"原理理解深度、工程实践能力和学习方法论"。准备好你的"战争故事"——那些解决过的棘手问题,往往比标准答案更能打动面试官。祝面试顺利!🚀