Files

68 lines
4.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: frontend.react.interview
title: React 面试题
type: interview
domain: frontend
stack: [react]
tags: [React, Hooks, 渲染, 面试]
level: intermediate
related: [frontend.react.hooks-rendering]
week: [7, 16]
---
# React 面试题
## 基础
### 【基础】React 组件什么时候会重新渲染?
**参考答案**:自身 state 变化、父组件渲染(即使 props 没变)、使用的 Context 值变化。渲染不等于 DOM 更新,React 会比较后只提交变化的部分。
**追问**:怎么避免子组件不必要的渲染?→ `memo` 包裹子组件并保证 props 引用稳定(`useMemo` / `useCallback`),或者把状态下移、把变化的部分拆成独立组件;React Compiler 可以自动处理部分记忆化。
### 【基础】为什么 Hooks 不能写在条件语句中?
**参考答案**:React 用 Hook 的调用顺序来对应每个 Hook 的状态,条件调用会导致顺序变化,状态错位。
**追问**:需要条件逻辑怎么办?→ 在 Hook 内部写条件,或者拆分组件。
### 【基础】`useEffect` 的执行和清理时机?
**参考答案**:在渲染提交到屏幕之后执行;依赖变化时,先执行上一次的清理函数,再执行新的 effect;组件卸载时执行清理。开发环境的严格模式会额外执行一次“挂载 → 卸载 → 挂载”来暴露缺少清理的问题。
**追问**:`useLayoutEffect` 有什么区别?→ 在 DOM 更新后、浏览器绘制前同步执行,用于测量布局,避免闪烁;会阻塞绘制,谨慎使用。
## 进阶
### 【进阶】setState 是同步还是异步的?
**参考答案**:调用后不会立即改变当前渲染中的值(状态是快照),更新会被批量处理并在之后重新渲染。React 18 起在事件、Promise、定时器中都会自动批量。依赖旧值的更新用函数式写法 `setX(x => x + 1)`。
**追问**:需要立即拿到更新后的 DOM 怎么办?→ 极少数情况可以用 `flushSync`,一般在 effect 中处理。
### 【进阶】React 和 Vue 的更新机制有什么区别?
**参考答案**:Vue 通过响应式系统精确追踪依赖,数据变化时只更新依赖它的组件;React 状态变化后从该组件开始重新执行渲染函数并比较,默认会渲染子树,靠 memo 等手段优化。Vue 的 `setup` 只执行一次,React 函数组件每次渲染都执行。
**追问**:哪种更好?→ 各有取舍:Vue 自动优化、心智负担小;React 模型简单(UI = f(state))、生态和并发特性丰富。
### 【进阶】服务端数据为什么不建议放在 Redux 里?
**参考答案**:服务端数据需要缓存、失效、后台刷新、重试、去重请求、分页等能力,自己在 Redux 中实现复杂且容易出错。TanStack Query 等库专门处理这些;全局 store 只放真正的客户端状态。
**追问**:TanStack Query 的 `staleTime` 和 `gcTime` 是什么?→ `staleTime` 决定数据多久后被视为过期(过期才会重新请求);`gcTime` 决定不再使用的缓存保留多久后被回收。
## 场景题
### 【场景题】设计一个长任务(Agent 生成报表)的前端界面,要注意什么?
**参考答案**:以服务端为准(任务 ID、刷新后恢复、幂等提交);`useReducer` 状态机;事件序号去重;重连时先取快照;失败区分可重试;取消等待后端确认;等待用户输入的交互。详见[长任务界面场景](scenarios/long-task-ui.md)。
**追问**:怎么测试?→ reducer 是纯函数,直接写单元测试覆盖各种事件序列;组件用 Testing Library 模拟事件订阅。
### 【场景题】搜索框输入时列表过滤很卡,怎么优化?
**参考答案**:输入框状态和列表过滤分离;用 `useDeferredValue` 让列表渲染延后,保证输入流畅;列表虚拟化;过滤计算 `useMemo`;数据量大时防抖或放到 Web Worker / 服务端。
**追问**:防抖和 `useDeferredValue` 的区别?→ 防抖固定延迟后才执行;`useDeferredValue` 由 React 调度,空闲时尽快渲染,可以被新的输入中断,不需要选择延迟时间。