【问题标题】:How to add Event Listeners to UseRefs within UseEffect如何在 UseEffect 中将事件侦听器添加到 UseRefs
【发布时间】:2021-03-10 15:12:09
【问题描述】:

我想将eventListener 添加到我的 React 组件中的节点。我正在选择带有useRef 钩子的节点。我是useCallback,因为useRef 在第一次渲染时是null

const offeringsContainer = useRef(null);

const setOfferingsContainer = useCallback((node) => {
  if (node !== null) {
    offeringsContainer.current = node;
  }
}, []);

我的问题是我的useEffectofferingContainer 参考所做的任何更改都没有反应。意思是,offeringContainer.currentnull

useEffect(() => {
    checkHeaderState();
    offeringsContainer.current.addEventListener("wheel", onOfferingsContainerWheel, { passive: false });
}, [offeringsContainer.current]);

这是我的 JSX:

return (
    <Fragment>
      <div className="card-business-products-services-title-text">
        Products &amp; Services
      </div>
      <div
        className="card-business-products-services-container"
        id="card-business-products-services-container"
        onWheel={onOfferingsContainerWheel}
        ref={setOfferingsContainer}
      >
        {renderOfferings()}
      </div>
    </Fragment>
);

我知道我做错了什么,但我的 useEffect 挂钩应该监听来自 offeringsContainer.current 的任何更改。

【问题讨论】:

  • 您可以简单地在 jsx 中分配 ref:ref={offeringsContainer},并且由于 useEffect 在访问 offeringsContainer.current 的第一个渲染之后运行将返回节点。您还需要将清理调用传递回您的 useEffect 的返回,以删除侦听器。但更好的是使用onwheel 合成事件
  • 为什么要给元素分配onWheel,还要手动添加监听器?
  • @pilchard 删除“被动:真”
  • 同时分配两个听众,所以选择一个或另一个。

标签: javascript reactjs use-effect usecallback use-ref


【解决方案1】:

您可以将offeringsContainer 传递到组件的refuseEffect 只会在第一次渲染时被调用,这就是为什么你的offeringsContainer.current 不会是null

而你在组件卸载后忘记移除监听器了。

你的代码应该是这样的;

const offeringsContainer = useRef(null);

useEffect(() => {
  checkHeaderState();
  offeringsContainer.current.addEventListener(
    "wheel",
    onOfferingsContainerWheel,
    { passive: false }
  );

  return () => offeringsContainer.current.removeEventListener("wheel");
}, []);

return (
  <Fragment>
    <div className="card-business-products-services-title-text">
      Products &amp; Services
    </div>
    <div
      className="card-business-products-services-container"
      id="card-business-products-services-container"
      onWheel={onOfferingsContainerWheel}
      ref={offeringsContainer}
    >
      {renderOfferings()}
    </div>
  </Fragment>
);

示例:https://codesandbox.io/s/wizardly-banzai-3fhju?file=/src/App.js

【讨论】:

    猜你喜欢
    • 2020-06-16
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    相关资源
    最近更新 更多