跳到主要内容

useEffectEvent

面试速答(30 秒版 TL;DR)

  • 如果题目明确是 React 18 stable,最稳的回答是:useEffectEvent 不是 React 18 的稳定内置 Hook。
  • 它想解决的是:在 effect 里既希望拿到“最新值”,又不希望因为这些值变化而让 effect 反复重跑。
  • React 18 中常见替代方案是:
    • 拆分 effect
    • 把与订阅无关的逻辑移到事件里
    • useRef 保存最新值
  • 面试时重点是把“订阅逻辑”和“读取最新值的逻辑”分开讲清楚。

1. 为什么会有这个方向

React 里经常有这种场景:

  • effect 负责建立订阅
  • 回调里又想读取最新的 state / props

例如:

useEffect(() => {
const id = setInterval(() => {
console.log(count)
}, 1000)

return () => clearInterval(id)
}, [])

这里会遇到典型的闭包旧值问题。

如果把 count 放进依赖:

useEffect(() => {
const id = setInterval(() => {
console.log(count)
}, 1000)
return () => clearInterval(id)
}, [count])

又会导致订阅频繁重建。

useEffectEvent 想解决的,就是这种张力。

2. React 18 里怎么答替代方案

2.1 用 useRef 保存最新值

const latestCount = useRef(count)

useEffect(() => {
latestCount.current = count
}, [count])

useEffect(() => {
const id = setInterval(() => {
console.log(latestCount.current)
}, 1000)
return () => clearInterval(id)
}, [])

2.2 拆 effect

把“建立连接”和“处理最新业务逻辑”拆开,不要把所有事情塞进同一个 effect。

2.3 重新审视是不是一定要 effect

有些逻辑其实应该放:

  • 事件处理函数
  • render 派生计算

而不是 effect。

3. React 18 面试里该怎么表述

建议按这个口径:

useEffectEvent 不是 React 18 stable 的标准 Hook,但它反映了 React 团队在解决 effect 闭包和订阅重建问题上的方向。React 18 里更常见的做法是拆 effect、用 useRef 存最新值,或者重新组织逻辑,避免 effect 承担过多职责。

4. 面试高频答法

Q1:useEffectEvent 是 React 18 的 Hook 吗?

不是,不应作为 React 18 稳定 API 背诵。

Q2:它想解决什么问题?

想解决 effect 中:

  • 订阅不想频繁重建
  • 但业务回调又想拿到最新值

这两个目标之间的冲突。

Q3:React 18 里怎么解决?

  • useRef 存最新值
  • 合理拆分 effect
  • 减少把所有逻辑都塞进 effect 的写法

常见追问

1)为什么 useRef 能做替代?

因为改 ref.current 不会触发重新渲染,但可以让异步回调读到最新值。

2)它能完全替代依赖数组吗?

不能。依赖数组解决的是“什么时候重新同步副作用”,不是单纯读取最新值。

易错点/坑

  • 在 React 18 面试里把它当稳定 Hook 回答。
  • 把“读取最新值”和“重新建立副作用”混为一谈。
  • 过度依赖 useRef,把真实依赖关系藏起来。

速记要点(可背诵)

  • useEffectEventReact 18 stable 不提供
  • 它针对的是 effect 闭包旧值与订阅重建冲突。
  • React 18 常见替代:拆 effect、useRef 存最新值、把逻辑移出 effect。