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

React中如何正确为ref绑定的自定义元素添加并清理事件监听?

问题原因

报错的核心是你在组件作用域声明的let eventRef是普通函数变量,每次组件重新渲染都会被重置,useEffect内部对它的赋值无法跨渲染周期保留,所以才会触发React的规则提示。

修复方案

你完全不需要额外声明eventRef变量,直接使用已有的textRef即可。另外要注意一个常见坑:原生addEventListener监听自定义事件不需要加on前缀,需要和自定义元素实际派发的事件名保持一致,你现在写的onCustomEvent大概率会监听不到事件。

修复后的完整代码如下:

export function App() {
  const textRef = useRef<DemoTextElement>(null);

  const logEvent = (e) => {
    console.log(e)
  }

  useEffect(() => {
    const element = textRef.current;
    if(!element) return;
    // 事件名要和自定义元素派发的名称一致,不要加on前缀
    element.addEventListener('customEvent', logEvent);

    return () => {
      element.removeEventListener('customEvent', logEvent);
    }
  }, [logEvent]) // 将logEvent加入依赖数组避免闭包问题

  return (
    <div className={styles.app}>
      <demo-text ref={textRef}/>
    </div>
  );
}
可选优化点
  • 如果logEvent函数逻辑不会变化,可以用useCallback包裹,避免useEffect频繁重新执行:
const logEvent = useCallback((e) => {
  console.log(e)
}, [])
  • 如果你确实需要单独存储绑定事件的元素引用,就再声明一个useRef来存,不要用普通let变量:
const eventRef = useRef<DemoTextElement | null>(null);
// 赋值时使用 eventRef.current = 目标元素

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:45:03