React Hooks:用于模态事件侦听器的 useEffect [英] React Hooks: useEffect for modal event listener

查看:34
本文介绍了React Hooks:用于模态事件侦听器的 useEffect的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

模态对话框包含许多子节点(反应节点),这些子节点可能会更改(例如,用户删除列表中的条目).这些交互触发了我的 onClick 方法,但由于单击列表项已从模态中删除,即使单击在模态内,模态也会关闭.

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

我在一个带有 ignoreNextClick 状态的类组件中处理了同样的问题,但必须有一个更简洁的解决方案,对吗?

 useEffect( () => {const onClick = ( 事件 ) =>{const menu = document.getElementById('singleton-modal');如果(!菜单)返回;//如果用户点击里面,不关闭菜单const targetInMenu = menu.contains( event.target );const targetIsMenu = menu === event.target;if ( targetInMenu || targetIsMenu ) 返回;onCloseModal();};window.addEventListener('click', onClick, false );返回 () =>window.removeEventListener('click', onClick, false );}, [ 孩子们 ] );

解决方案

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

useEffect 调用如下所示:

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

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

event.stopPropagation()}角色=演示">{孩子们}

`

我还添加了角色介绍,以使模态更易于访问和符合 aria.

I have a modal dialog that I want to close if the user clicks outside of the modal. I have written the following useEffect code but I run into following issue:

The modal dialog contains a number of children (React Nodes) and those children might change (e.g. the user deletes an entry of a list). Those interactions trigger my onClick method but as the clicked list item has been removed from the modal, the modal closes even though the click was within the modal.

I thought adding [ children ] at the second parameter for useEffect would cleanup the old effect event listener quick enough that the method does not run again but this is not the case.

I handled the same issue in a class component with a ignoreNextClick-state but there must be a cleaner solution, right?

    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 ] );

解决方案

I found a solution that does not require any sort of storing old props.

The useEffect call looks like this:

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

Adding the following click listener to the modal directly will stop the window click-listener from being called if the user clicked inside the modal.

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

I also added the role presentation to make the modal more accessible and aria-conform.

这篇关于React Hooks:用于模态事件侦听器的 useEffect的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆