首页 > 解决方案 > 挂载和卸载的 useEffect 缺少依赖项

问题描述

我的代码中有以下内容...

useEffect(() => {
    document.addEventListener("mousedown", handleClick, {capture: true})
    return () => document.removeEventListener("mousedown", handleClick, {capture: true})
}, []);

据我了解,如何仅在组件安装/卸载时触发事件。但是,当我使用它时,我会收到一条警告,说它handleClick作为依赖项丢失了?这是使用useEffect()这种方式时的预期警告还是我的方法有问题?

useEffect经过一番搜索后,我看到了一篇建议将我尝试的功能移到其中的帖子

    useEffect(() => {
        function handleClick(e) {
            // click on node or any of its children
            if (node.current.contains(e.target)){ return }
            // otherwise the code below will execute when clicking off of node
            onOutsideClick();
        }

        // add event listener on mount
        document.addEventListener('mousedown', handleClick, {capture: true});
        // clean up on unmount
        return () => document.removeEventListener('mousedown', handleClick, {capture: true});
    
    }, []);

但是现在警告是onOutsideClick哪个组件由另一个组件设置并传递给处理程序。

我只希望它在组件安装和卸载时运行,那么我该如何解决这个问题?我看到其他帖子提到偶尔会禁用某些代码部分的消息,但这似乎并不可取

更新:在Hooks FAQ中找到了一些有用的信息

因此,我目前的解决方案似乎很好,但希望对解决方案有一些反馈。

当前的解决方案涉及传递onOutsideClick​​给满足警告的依赖数组。现在的问题是,每次父组件渲染和设置onOutsideClick时,我们useEffect都会重新渲染,这是不必要的。为了解决这个问题,我选择设置传递给的回调,onOutsideClickuseCallback()防止重新渲染。

const handleOutsideClick = useCallback(() => setState(null), []);
...
<OutsideClickHandler onOutsideClick={ handleOutsideClick }>...</OutsideClickHandler>

标签: reactjs

解决方案


useEffect(() => {
    // this goes when component mounted you dont need to check anything
        document.addEventListener("mousedown", handleClick, {capture: true})
    
    // this will fire when component unmounts
    return () => document.removeEventListener("mousedown", handleClick, {capture: true})
}, []);

例子


useEffect(() => {
        document.addEventListener('click', handleClickOutside, true);

        return () => {
            document.removeEventListener('click', handleClickOutside, true);
        };
    }, []);


推荐阅读