使用 useRef addEventListener

Posted

技术标签:

【中文标题】使用 useRef addEventListener【英文标题】:Using useRef addEventListener 【发布时间】:2021-04-03 22:44:40 【问题描述】:

我将useRef 用于addEventListener 但不起作用,这里有什么问题吗?

父组件:

const parent = () => 
  const el = useRef()
  const element = el.current && el.current 

  useEffect(() => 
    if (element) 
      const scrollHandler = e => 
        console.log(e);
      ;

      element.addEventListener("scroll", scrollHandler);

      return () => 
        element.removeEventListener("scroll", scrollHandler);
      ;
    
  , [element]);

  return (
    <Child ref=el />
  )

子组件:

const child = React.forwardRef((props, ref) => 
  return (
    <div ref=ref>something...</div>
  )
)

【问题讨论】:

要使scroll 事件起作用,Child 组件的内容需要有足够的高度使网页可以滚动。尝试在Child 组件中的div 元素上设置200vh 高度。然后您将看到scroll 事件正常运行。 Useref 不会触发重新渲染,并在 useEffect 之前绑定 ref 对象。只需使用不带元素的 el.current。 ***.com/users/6094348/yousaf 是的,你是对的,我有足够的滚动元素,但仍然无法使用 ***.com/users/6165701/cenk-%c3%87etinkaya按照你说的做了,还是不行。 这里是the working demo。要使scroll 事件作用于一个元素,该元素应该是可滚动的,并且您需要在useEffect 挂钩中使用el.current 而不是element 【参考方案1】:

将您的父组件更改为此以避免stale state


const parent = () => 
  const el = useRef();

  useEffect(() => 
    if (el.current) 
      const scrollHandler = (e) => 
        console.log(e);
      ;

      el.current.addEventListener("scroll", scrollHandler);

      return () => 
        el.current.removeEventListener("scroll", scrollHandler);
      ;
    
  , [el.current]);

  return <Child ref=el />;
;

【讨论】:

@Yousaf 我没有说 Stale Propselement constant is unneccessary here and it may result in 陈旧状态` ***.com/users/11432102/taghi-khavari 谢谢老兄,你能再次看到我的问题吗?我做了一些编辑 不客气。我改变了我的答案。你不需要element variable 直接使用你的el variable ***.com/users/11432102/taghi-khavari 非常感谢。 很高兴我能帮上忙 :)

以上是关于使用 useRef addEventListener的主要内容,如果未能解决你的问题,请参考以下文章

createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步

createRef和useRef区别——useRef的使用——forwardRef完成类组件的绑定—— useImperativeHandle——映射ref对象——更新同步

如何使用 useRef() 进行验证

我应该使用 createRef 还是 useRef,为啥?

使用 useRef 更改输入值

useRef 有时不会更新,只打印对象