一、状态管理实战模式
1️⃣ 局部状态 vs 全局状态拆分原则
✅ 局部状态(优先)
- 表单
- 弹窗开关
- hover / loading
- 局部 UI 状态
用:
js
useState
useReducer原则:
状态尽量靠近使用它的组件
✅ 全局状态
不要滥用 Context。
推荐:
- 轻量场景:Context + selector
- 中大型项目:zustand / jotai
- 超复杂:redux-toolkit
高级优化点:
- 切 store(按域拆分)
- selector 精准订阅
- 避免顶层大对象
2️⃣ useReducer 实战场景
适合:
- 多字段联动表单
- 状态机流程
- 复杂业务逻辑
示例:
js
const [state, dispatch] = useReducer(reducer, initialState)优势:
- 状态集中
- 可测试
- 可追踪
面试亮点:
用 useReducer 做过轻量状态机
二、副作用管理最佳实践
3️⃣ 请求封装:useRequest 模式
不要直接在组件里写 fetch。
推荐结构:
js
function useRequest(service, options) {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(false)
const abortRef = useRef(null)
const run = useCallback(async (...args) => {
abortRef.current?.abort()
const controller = new AbortController()
abortRef.current = controller
setLoading(true)
const result = await service(...args, controller.signal)
setData(result)
setLoading(false)
}, [service])
useEffect(() => {
return () => abortRef.current?.abort()
}, [])
return { data, loading, run }
}实战点:
- 支持取消请求
- 支持重复调用
- 防止内存泄漏
- 保证引用稳定
4️⃣ 流式输出场景(AI Chat)
你最近在准备 AI Chat 架构,这个很关键。
核心问题:
- 流式更新会导致频繁 re-render
- 长对话会卡顿
- 需要可中断
优化方案:
- useRef 存缓存
- RAF 合并更新
- useTransition 降低优先级
- 消息分层 memo
三、性能优化实战
5️⃣ useMemo / useCallback 正确使用方式
❌ 常见错误
- 到处包 useCallback
- deps 填不对
- 为优化而优化
✅ 正确使用场景
- 传给 React.memo 子组件
- 作为 useEffect 依赖
- 大计算
6️⃣ 大列表优化
场景:2000 条消息
实战组合:
- 虚拟列表
- 消息组件 React.memo
- key 稳定
- 状态拆分(不要 messages 整体替换)
错误示例:
js
setMessages([...messages, newMsg])优化:
- 使用函数式更新
- 拆成 map + id 存储
四、闭包问题实战解决方案
7️⃣ 定时器 Hook 封装
错误写法:
js
setInterval(() => console.log(count), 1000)正确封装:
js
function useInterval(callback, delay) {
const savedCallback = useRef(callback)
useEffect(() => {
savedCallback.current = callback
})
useEffect(() => {
const id = setInterval(() => {
savedCallback.current()
}, delay)
return () => clearInterval(id)
}, [delay])
}优点:
- 永远拿最新 state
- 不重新注册 interval
五、Context 高级用法
8️⃣ 避免全量刷新
问题:
Context value 改变 → 全部子组件重渲染
解决:
- 拆分多个 context
- useMemo 包裹 value
- selector 模式
六、并发特性实战
9️⃣ useTransition 场景
搜索过滤:
js
const [isPending, startTransition] = useTransition()
const onSearch = (value) => {
setInput(value)
startTransition(() => {
setFilteredList(filter(value))
})
}效果:
- 输入不卡顿
- 过滤低优先级
🔟 useDeferredValue 场景
用于:
- 大表格
- 数据图
与 useMemo 区别:
- useMemo 是缓存
- useDeferredValue 是调度延迟
七、Hooks 设计规范(团队级)
1️⃣1️⃣ 自定义 Hook 设计原则
- 命名 useXxx
- 单一职责
- 不暴露内部状态结构
- 返回对象结构稳定
推荐:
js
return useMemo(() => ({
data,
loading,
run
}), [data, loading, run])1️⃣2️⃣ 依赖数组规范
原则:
- 不要忽略 ESLint 提示
- 不要随便加 eslint-disable
- 不要把对象写进 deps(除非 memo)
八、企业级最佳实践总结
状态设计
- 状态最小化
- 数据归一化
- 拆分粒度
副作用设计
- 所有副作用必须可清理
- 必须考虑组件卸载
- 请求必须可取消
性能设计
- 默认不过度优化
- 关键路径优化
- 用 profiler 验证
九、高级前端面试总结
在 React 项目中,我通常遵循状态就近原则,用 useReducer 处理复杂逻辑,用自定义 Hook 封装副作用,并结合 useTransition 优化长列表或搜索场景。对闭包问题和并发渲染机制有深入理解,能在高频更新场景下保持 UI 流畅。
十、如果你是做 AI Chat / 大型系统
- 流式渲染 Hook 设计
- 可中断机制
- 并发优先级控制
- 虚拟列表
- 状态分层