You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

组件挂载时注册的事件处理器无法获取最新props值的原因

问题解答

你的猜想完全正确,下面是这个行为背后的具体原因:

函数组件的渲染与闭包捕获

React函数组件每次接收到新的props(或state变化)时,会重新执行整个组件函数,生成全新的props对象和组件内部的所有函数(包括displayCount)。

你的第一个useEffect依赖项是空数组[],这意味着它只会在组件第一次挂载时执行一次:

  • 此时绑定的displayCount是第一次渲染时创建的函数,它通过闭包捕获了当时的props对象(也就是初始的count值)。
  • 后续父组件传递新的count时,组件会重新渲染,生成新的props和新的displayCount函数,但旧的displayCount已经被绑定到window.focus事件上,且没有被替换——因为第一个useEffect不会再执行,所以事件触发时,始终是旧的displayCount在执行,它引用的还是第一次渲染时的props,自然只能打印初始值。

为什么Ref能解决问题

useRef创建的对象是一个可变的容器,它的current属性不会被React的渲染机制捕获:

  • 每次count更新时,第二个useEffect会触发,把最新的count赋值给countRef.current。
  • displayCount访问countRef.current时,直接读取的是这个容器的最新值,不受闭包捕获的旧值影响,所以能打印出最新的count。

补充:另一种解决方案

除了用Ref,你也可以让第一个useEffect监听count的变化,每次count更新时重新绑定事件:

useEffect(() => {
  const displayCount = () => {
    console.log("count prop -> " + props.count);
  };
  window.addEventListener('focus', displayCount);
  return () => {
    window.removeEventListener('focus', displayCount);
  };
}, [count]); // 依赖count,每次count变化重新执行

这种方式每次count更新时,都会创建新的displayCount函数并重新绑定,确保事件触发时引用的是最新的props。


内容的提问来源于stack exchange,提问作者RDX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:36:02