React Hooks: useEffect для модального прослушивателя событий - PullRequest
0 голосов
/ 24 июня 2019

У меня есть модальное диалоговое окно, которое я хочу закрыть, если пользователь нажимает за пределами модального.Я написал следующий код useEffect, но столкнулся со следующей проблемой:

Модальное диалоговое окно содержит несколько дочерних элементов (узлов реагирования), и эти дочерние элементы могут измениться (например, пользователь удаляет запись в списке).Эти взаимодействия запускают мой метод onClick, но поскольку элемент списка, по которому щелкнули мышью, был удален из модального режима, модальный режим закрывается, даже если щелчок был внутри модального элемента.

Я подумал, что добавление [children] ко второму параметру для useEffect позволит достаточно быстро очистить старый прослушиватель событий эффекта, чтобы метод не запустился снова, но это не так.

Я обработал ту же проблему в компоненте класса с ignoreNextClick состоянием, но должно быть более чистое решение, верно?

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

Ответы [ 2 ]

0 голосов
/ 24 июня 2019

Я нашел решение, которое не требует какого-либо хранения старых реквизитов.

Вызов 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>`

Я также добавил презентацию роли, чтобы сделать модал более доступным и соответствующим арии.

0 голосов
/ 24 июня 2019

Вы можете проверить родительский модальный от event.target. Если текущая цель находится в пределах модального значения, тогда return.

Вы можете использовать ближайший , чтобы сделать это.

См. Следующее решение.

...

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

...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...