React 面试题高频清单与回答要点汇总
前端面试高频问题清单(React 方向),涵盖 React 核心与机制、Hooks 与状态管理、性能优化与渲染控制、工程化与架构、前端质量与稳定性、系统设计与经验题(高级)等方面。
React 核心与机制
JSX 的本质是什么,编译后产物长什么样
要点:
- JSX 是语法糖,编译为 jsx/jsxDEV 或 React.createElement 调用
- 表达式是 JS,条件渲染/循环由 JS 控制
- 编译期可做静态优化,减少运行时开销
追问: - 新 jsx runtime 和旧 runtime 的差别是什么
- 如何在 TS/构建里配置 jsxImportSource
Virtual DOM 和 Reconciliation 解决了什么问题
要点:
- 用声明式 UI 生成变更,统一 diff 和 patch
- 提供跨平台抽象(Web/Native/Canvas)
- diff 基于 key 和类型,减少实际 DOM 变更
追问: - React diff 的启发式规则有哪些
- 真实 DOM 仍然是最终性能瓶颈吗
为什么需要 key,错误 key 会导致什么问题
要点:
- key 是列表项稳定身份,帮助复用实例
- 错误 key 导致状态错位、输入错乱、动画异常
追问: - 什么时候可以使用 index 作为 key
- key 变化会触发什么生命周期行为
setState / useState 为什么是异步(或批处理),并发模式下有什么变化
要点:
- 批处理减少重复渲染,保证一致性
- 同一事件循环内合并更新,异步边界不同
- 并发模式下更新可中断,优先级不同
追问: - 如何强制同步更新,什么时候需要
- flushSync 带来的风险是什么
受控组件 vs 非受控组件,选择依据是什么
要点:
- 受控组件由 state 驱动,便于校验和联动
- 非受控组件用 ref 读取,性能好,适合大表单
- 银行业务常用受控或混合模式以保证一致性
追问: - 大表单性能问题如何处理
- 如何处理输入延迟和体验
React 的渲染流程是怎样的(render -> commit)
要点:
- render 阶段纯计算,可中断不触 DOM
- commit 阶段写 DOM 和执行布局副作用
- effect 在 commit 后运行,避免阻塞
追问: - useLayoutEffect 和 useEffect 的区别
- 为什么 render 阶段必须是纯函数
Fiber 架构解决了什么问题,和调度优先级有什么关系
要点:
- Fiber 让渲染可拆分、可暂停、可恢复
- 通过 lanes 和 scheduler 管理优先级
- 支持并发特性和更好的交互响应
追问: - lane 的优先级如何影响渲染顺序
- 并发渲染有哪些风险点
Hooks 与状态管理
Hooks 规则的原因是什么,违反会发生什么
要点:
- 保证 hooks 调用顺序一致,正确关联 state
- 违反规则会导致 state 绑定错位或运行时报错
追问: - 为什么不能在条件或循环里调用 hooks
- 如何用自定义 hook 复用条件逻辑
useEffect 的执行时机与清理机制,依赖数组的语义
要点:
- 在 commit 后执行,清理在下一次执行前或卸载时
- 依赖数组描述引用变化,影响是否重跑
- 严格模式下开发环境会双调用帮助发现问题
追问: - 如何避免依赖过多导致频繁执行
- useEffect 里请求如何防止竞态
闭包陷阱(stale closure)如何出现,怎么避免
要点:
- 回调捕获旧 state,导致读到过期值
- 用依赖数组、函数式更新或 ref 保存最新值
追问: - 为什么 setState 的函数式更新能避免 stale
- useRef 保存最新值的风险是什么
useMemo / useCallback 的边界与误用成本
要点:
- 用于昂贵计算或稳定引用,避免子组件重渲染
- 过度使用会增加复杂度和内存占用
追问: - 如何量化是否需要 memo
- useMemo 和 memo 的组合陷阱有哪些
useRef 的典型场景与不触发渲染的原因
要点:
- 保存可变值、DOM 引用、定时器句柄
- ref 改变不触发渲染,避免渲染循环
追问: - 何时应该用 state 替代 ref
- forwardRef 与 useImperativeHandle 的使用场景
自定义 Hook 如何设计,如何做到可组合与可测试
要点:
- 单一职责,暴露最小 API,组合优先
- 避免隐式副作用,便于单元测试和复用
追问: - 如何处理 hook 之间的依赖顺序
- 如何让 hook 在 SSR 兼容
Context 的适用边界,如何避免过度重渲染
要点:
- 适合低频全局配置,如主题、语言、权限
- 拆分多个 context 或使用选择器减少重渲染
追问: - context 与状态库的边界如何划分
- 如何在大型应用中组织 context 层级
性能优化与渲染控制
React.memo 什么时候有效,什么时候无效
要点:
- props 稳定且渲染成本高时有效
- 每次都新建 props/函数会使 memo 失效
追问: - 自定义比较函数的代价和风险
- memo 是否能解决所有 re-render
列表渲染性能问题如何定位与优化
要点:
- 使用虚拟列表、分页、懒加载
- 避免逐项重渲染,拆分行组件并 memo
追问: - 虚拟列表对可访问性有什么影响
- 如何处理动态高度列表
如何减少不必要的 re-render(状态提升、拆分、memo)
要点:
- 状态就近管理,减少顶层 state 变化
- 拆分组件,稳定 props 引用
- 选择合适的状态库或 selector
追问: - 状态提升的代价与替代方案是什么
- 如何定位是 state 变化还是 props 变化
key 与 diff 的关系,在列表插入/排序时如何稳定
要点:
- 稳定 key 保证复用,避免重建子树
- 业务主键优于 index,银行业务要避免错位
追问: - key 变化会导致什么副作用
- 如何处理无唯一 ID 的列表
如何定位性能瓶颈(Profiler / performance)
要点:
- React DevTools Profiler 分析 commit 时间
- 浏览器 Performance 分析长任务和布局
追问: - 如何把性能数据和业务场景关联
- 如何在生产环境采集性能指标
工程化与架构
Redux vs Zustand vs React Query 的取舍
要点:
- Redux 适合复杂全局状态和严格约束
- Zustand 轻量灵活,适合中小规模
- React Query 管理服务端状态与缓存
追问: - 是否需要全部使用一个方案
- 如何避免状态重复来源
服务端状态 vs 客户端状态如何划分
要点:
- 服务端状态是事实来源,客户端状态是 UI 和临时数据
- 银行业务需强调一致性和权限边界
追问: - 乐观更新如何回滚
- 如何处理服务端数据版本冲突
请求与副作用管理:错误处理、取消请求、重试策略
要点:
- 统一错误分类和重试策略,支持 AbortController
- 防止竞态,保证最新请求覆盖旧请求
- 银行业务需要严格失败可追踪
追问: - 幂等请求如何设计
- 如何处理网络抖动下的用户体验
表单方案的选择与架构(受控成本、验证、性能)
要点:
- 复杂表单可用 schema 驱动,分层验证
- 混合受控降低性能成本,分区渲染
- 银行业务强调字段校验、权限和审计
追问: - 如何实现联动与动态字段
- 如何记录表单变更审计
组件设计模式:Container/Presentational、Hooks 化
要点:
- 逻辑与视图分离,提升复用与测试
- hooks 封装业务逻辑,组件更轻量
追问: - 什么时候选择容器组件而不是 hook
- 如何组织领域组件与通用组件
组件库如何设计(API 设计、可扩展、主题与样式隔离)
要点:
- 统一设计语言和 tokens,API 稳定
- 支持主题、国际化、可访问性
- 样式隔离避免业务污染
追问: - 如何管理组件库的版本与兼容
- 如何设计可扩展的 slots 或 render props
路由与代码拆分:动态 import、prefetch
要点:
- 路由级拆分降低首屏包体
- 预取关键路径,减少交互等待
- 银行业务要结合权限和白名单策略
追问: - 动态 import 的失败回退怎么做
- 预取策略如何避免浪费流量
CSR vs SSR vs SSG 的权衡与适用场景
要点:
- CSR 交互快,SEO 弱,适合登录后系统
- SSR 改善首屏和 SEO,复杂度高
- SSG 适合内容稳定页面
追问: - SSR 下的鉴权与数据隔离如何做
- Hydration 失败的常见原因
前端质量与稳定性
错误边界能解决什么问题,不能解决什么问题
要点:
- 捕获渲染期错误,隔离模块故障
- 不能捕获事件回调和异步错误
追问: - 事件错误如何统一处理
- 错误边界如何与监控系统集成
如何设计日志与埋点策略(前端可观测性)
要点:
- 统一埋点协议,包含用户、渠道、行为
- 加入 traceId,便于跨端链路追踪
- 银行业务需脱敏和合规审计
追问: - 如何平衡埋点覆盖和性能
- 如何采集用户行为的因果链路
Web 性能指标(FCP/LCP/CLS)如何优化
要点:
- 首屏资源优先级、关键路径优化
- 减少布局抖动,稳定占位
- 通过缓存和分包降低加载成本
追问: - CLS 在动态表单如何控制
- 如何在生产收集 Web Vitals
如何保证大型前端项目的可维护性(模块边界、依赖治理)
要点:
- 清晰模块边界与领域拆分
- 统一规范、lint、测试与发布流程
- 银行业务强调安全审计与依赖合规
追问: - 如何控制依赖膨胀与重复
- 如何做渐进式重构
系统设计与经验题(高级)
设计一个可配置表单引擎,如何处理联动与校验
要点:
- schema 描述结构与规则,渲染器可插拔
- 事件总线处理联动,分层校验与异步校验
- 审计记录字段变更与提交结果
追问: - 如何处理表单版本演进
- 如何做字段级权限控制
设计一个可扩展的组件库(主题、国际化、可访问性)
要点:
- 设计 tokens 与样式系统,支持主题切换
- 国际化与 RTL 兼容,可访问性达标
- 文档与示例驱动使用一致性
追问: - 如何设计可扩展 API 避免破坏性变更
- 如何做组件库的自动化回归测试
设计一个复杂页面的拆分策略(数据流、状态边界)
要点:
- 以业务域拆分,明确数据流方向
- 状态就近管理,跨域用事件或共享状态
- 关键模块支持懒加载
追问: - 如何处理跨模块联动
- 如何分离业务逻辑和框架逻辑
如何避免 props drilling(Context、组合、状态下沉)
要点:
- 使用 context 或状态库管理共享状态
- 组件组合和 slots 减少传参层级
- 状态下沉到需要的最小范围
追问: - Context 更新导致的性能问题怎么解决
- 组合模式如何与类型系统协作
如何推动跨团队协作与技术决策(RFC、技术债管理)
要点:
- RFC 明确问题、方案、风险和回滚
- 技术债量化,排期治理
- 银行业务重视合规、安全与审计
追问: - 如何在高合规环境下推动创新
- 如何评估架构改造收益