聊聊闭包陷阱问题,以及如何解决
结论:函数组件每次 render 都产生新闭包;异步回调/订阅如果持有旧闭包就会读到旧 state(stale closure)。解决思路是“让依赖显式化”或“用 ref 保存最新值”。
1. 典型表现
setTimeout/订阅回调里拿到的 state 不是最新的- effect 依赖漏写导致逻辑不更新
2. 常用解法
- 函数式更新:
setState((prev) => ...) useRef:把最新值写到ref.current,回调里读 ref- 正确依赖数组:让 effect 在依赖变化时重新注册
3. 面试加分点
- 说明“闭包是 JS 语义,不是 React bug”
- 并发下要注意外部 store 一致性:必要时用
useSyncExternalStore