代码之家  ›  专栏  ›  技术社区  ›  peter flanagan

使用钩子检测单击外部反应组件

  •  3
  • peter flanagan  · 技术社区  · 6 年前

    我发现我正在一个应用程序中重用行为,当用户在一个元素外单击时,我可以隐藏它。

    引入钩子后,我是否可以将它放入钩子中,并在各个组件之间共享,以节省在每个组件中编写相同的逻辑?

    我在一个组件中实现了它,如下所示。

    const Dropdown = () => {
        const [isDropdownVisible, setIsDropdownVisible] = useState(false);   
        const wrapperRef = useRef<HTMLDivElement>(null);
    
        const handleHideDropdown = (event: KeyboardEvent) => {
            if (event.key === 'Escape') {
                setIsDropdownVisible(false);
            }
        };
    
        const handleClickOutside = (event: Event) => {
            if (
                wrapperRef.current &&
                !wrapperRef.current.contains(event.target as Node)
            ) {
                setIsDropdownVisible(false);
            }
        };
    
        useEffect(() => {
            document.addEventListener('keydown', handleHideDropdown, true);
            document.addEventListener('click', handleClickOutside, true);
            return () => {
                document.removeEventListener('keydown', handleHideDropdown, true);
                document.removeEventListener('click', handleClickOutside, true);
            };
        });
    
        return(
           <DropdownWrapper ref={wrapperRef}>
             <p>Dropdown</p>
           </DropdownWrapper>
        );
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Paul Fitzgerald    6 年前

    这是可能的。

    可以创建一个名为 useComponentVisible

    import { useState, useEffect, useRef } from 'react';
    
    export default function useComponentVisible(initialIsVisible) {
        const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible);
        const ref = useRef<HTMLDivElement>(null);
    
        const handleHideDropdown = (event: KeyboardEvent) => {
            if (event.key === 'Escape') {
                setIsElementVisible(false);
            }
        };
    
        const handleClickOutside = (event: Event) => {
            if (ref.current && !ref.current.contains(event.target as Node)) {
                setIsElementVisible(false);
            }
        };
    
        useEffect(() => {
            document.addEventListener('keydown', handleHideDropdown, true);
            document.addEventListener('click', handleClickOutside, true);
            return () => {
                document.removeEventListener('keydown', handleHideDropdown, true);
                document.removeEventListener('click', handleClickOutside, true);
            };
        });
    
        return { ref, isComponentVisible, setIsComponentVisible };
    }
    

    然后,在组件中,您希望添加功能以执行以下操作:

    const DropDown = () => {
    
        const { ref, isComponentVisible } = useComponentVisible(true);
    
        return (
           <div ref={ref}>
              {isComponentVisible && (<p>Going into Hiding</p>)}
           </div>
        );
    
    }
    

    找到一个 codesandbox 这里是例子。