【问题标题】:React Hooks : UseRef not recognizing Event from Material UI SelectReact Hooks:UseRef无法识别来自Material UI Select的事件
【发布时间】:2020-01-16 22:02:52
【问题描述】:

我正在使用 React Hooks。我正在尝试使用 useRef 触发 onclick 事件。


    const component1: React.FC<Props> = props {
      const node =useRef<HTMLDivElement>(null);

      const ClickListener = UseCallback((e:any)=>{
        if(node.current.contains(e.target))
         console.log("Event Contained");
        else console.log("Event not Contained");
      },[]);

      return (
        <div ref={node} onClick={ClickListener}>
         <FormControl>
           <InputLabel>{text}</InputLabel>
           <Select> {contents} </Select>
         </FormControl>
        </div>
      );
    };

我有这个由 componentX 和 componentY 调用的 Component1。

当打开componentY的选择菜单时,上面的代码无法识别componentX的节点上的onclick事件。

只有在关闭 ComponentY 的选择菜单并再次单击 ComponentX 后才能识别该事件。 关于为什么无法识别的任何建议。我正在使用 Material UI 的选择。

【问题讨论】:

    标签: javascript reactjs material-ui react-hooks


    【解决方案1】:

    使用回调引用。

    引用 API 文档:

    请记住,useRef 不会在其内容更改时通知您。 改变 .current 属性不会导致重新渲染。如果你想 在 React 将 ref 附加或分离到 DOM 节点时运行一些代码, 您可能想改用callback ref

    编辑

    很抱歉将您引向错误的方向。我对使用回调 ref 的建议不适合您的代码。

    您的回调工作正常,并且能够正确使用 div 引用。
    打开其他组件中的 Select 时,您感觉回调不起作用的原因是 Select 使用鼠标捕获来检测弹出窗口外的点击。
    因此,当您的下拉菜单打开时,单击其他组件 div 根本不会到达该 div,它被 Select 消耗。后续点击效果很好。
    这不仅适用于您的组件,也适用于 dom 中的任何其他元素。

    见:https://codesandbox.io/s/silly-star-k430x

    【讨论】:

    • 谢谢!使用 callbackref 作为&lt;div ref={ClickListener} onClick={ClickListener}&gt; 显示以下错误类型'(e:any,node:HTMLDivElement)=> void'不可分配给类型'string | (((实例:HTMLDivElement | null)=> void)| RefObject |空 |未定义'。关于我在哪里使用 Call back ref 的错误的任何建议。
    • 是的,选择的鼠标事件不允许我实现这一点。我尝试了 mouseclick、mouseenter 和 mouseleave 选项,但它的行为相同。对替代方法有什么见解吗?
    • 用自定义下拉菜单替换 Material UI 选择有帮助。
    【解决方案2】:

    您应该将依赖列表中的node 传递给 useCallback 方法。 否则,在定义ClickListener 时引用nullnode 不会更新。

    通过docs - useCallback。 useCallback 避免了每次调用组件函数时都重新定义函数。因此,函数定义中的任何全局变量都必须列在依赖数组中,这样当依赖发生变化时,react 就会重新定义函数。

     const ClickListener =UseCallback((e:any)=>{
        if(node.current.contains(e.target))
        console.log("Event Contained");
        else console.log("Event not Contained");
        },[node]);
    

    【讨论】:

    • 谢谢!但添加依赖后它的行为仍然相同。
    猜你喜欢
    • 1970-01-01
    • 2018-09-11
    • 2021-06-27
    • 2021-04-22
    • 2020-10-20
    • 2021-03-12
    • 2020-08-12
    • 2021-08-20
    • 2019-07-27
    相关资源
    最近更新 更多