【问题标题】:React Hooks: useEffect for modal event listenerReact Hooks:模式事件监听器的 useEffect
【发布时间】:2019-11-06 08:04:08
【问题描述】:

我有一个模式对话框,如果用户在模式之外单击,我想关闭它。我编写了以下 useEffect 代码,但遇到了以下问题:

模态对话框包含许多子节点(React 节点),这些子节点可能会发生变化(例如,用户删除列表的条目)。这些交互触发了我的 onClick 方法,但是由于单击的列表项已从模态中删除,因此即使单击在模态中,模态也会关闭。

我认为在 useEffect 的第二个参数中添加 [children] 会足够快地清理旧的效果事件侦听器,以使该方法不会再次运行,但事实并非如此。

我在具有ignoreNextClick-state 的类组件中处理了同样的问题,但必须有更简洁的解决方案,对吧?

    useEffect( () => {
        const onClick = ( event ) => {
            const menu = document.getElementById( 'singleton-modal' );
            if ( !menu ) return;

            // do not close menu if user clicked inside
            const targetInMenu = menu.contains( event.target );
            const targetIsMenu = menu === event.target;
            if ( targetInMenu || targetIsMenu ) return;

            onCloseModal();
        };

        window.addEventListener( 'click', onClick, false );

        return () => window.removeEventListener( 'click', onClick, false );
    }, [ children ] );

【问题讨论】:

    标签: javascript reactjs react-hooks use-effect


    【解决方案1】:

    我找到了一个不需要任何形式存储旧道具的解决方案。

    useEffect 调用如下所示:

    useEffect( () => {
            const onClickOutside = () => onCloseModal();
            window.addEventListener( 'click', onClickOutside, false );
            return () => window.removeEventListener( 'click', onClickOutside );
        }, [] );
    

    如果用户在模态框内单击,直接将以下单击侦听器添加到模态将停止调用窗口单击侦听器。

    <div
        className={`modal ${ classes }`}
        onClick={event => event.stopPropagation()}
        role="presentation"
    >
       {children}
    </div>`
    

    我还添加了角色演示,以使模式更易于访问和符合 aria-conform。

    【讨论】:

      【解决方案2】:

      您可以从event.target 检查模态的父级。 如果当前目标在模态范围内,则return

      您可以使用closest 来执行此操作。

      请参阅以下解决方案。

      ...
      
          if (event.target.closest( '.singleton-modal' ) || event.target.classList.contains('singleton-modal')) {
             return;
          }
      
      ...
      

      【讨论】:

      • 与 event.target 相同的问题已从 DOM 中删除(我想这是问题所在) event.target.closest 不再在目标层次结构中找到模式。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      相关资源
      最近更新 更多