useEffect 缺少挂载和卸载的依赖项

时间:2021-03-18 00:04:51

标签: reactjs

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

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 的,它是由另一个组件设置并传递给处理程序的 prop。

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

更新:在 Hooks FAQ

中找到了一些关于此的有用信息

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

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

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

1 个答案:

答案 0 :(得分:1)

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);
        };
    }, []);