Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs useEffect未正确删除事件_Reactjs - Fatal编程技术网

Reactjs useEffect未正确删除事件

Reactjs useEffect未正确删除事件,reactjs,Reactjs,我面临一个问题,组件呈现子组件,即组件。 组件有两个道具一个是布尔值,另一个是函数。当用户单击按钮时将显示背景,背景只是一个隐藏在用户单击时的div 更改布尔属性时,组件会动态添加事件侦听器,并在用户单击文档上的任意位置时删除侦听器 我使用基于类的生命周期挂钩成功地添加了此功能,但在使用React挂钩替换组件时遇到了问题 我知道有一个名为useffect的钩子,它可以替换componentDidMount、componentWillUnmount和componentdiddupdate的行为,但

我面临一个问题,
组件呈现子组件,即
组件。
组件有两个
道具
一个是布尔值,另一个是函数。当用户单击按钮时将显示背景,背景只是一个隐藏在用户单击时的
div

更改布尔属性时,
组件会动态添加事件侦听器,并在用户单击文档上的任意位置时删除侦听器

我使用基于类的生命周期挂钩成功地添加了此功能,但在使用React挂钩替换组件时遇到了问题

我知道有一个名为
useffect
的钩子,它可以替换
componentDidMount
componentWillUnmount
componentdiddupdate
的行为,但我对
useffect
的实现并不是基于已更改的属性删除侦听器。即使背景是隐藏的,听众也在不点击按钮的情况下工作,为什么林特会抱怨

React Hook useEffect缺少依赖项:“addEvents”和 “移除事件”。包括它们或删除依赖项数组。 (反应钩/详尽的DEP)

如何修复此行为并使此组件成为类
组件

具有类组件的功能:

//背景的CSS样式
常量自定义样式={
背景色:“rgba(0,0,0,5)”,
位置:“绝对”,
排名:0,
左:0,,
右:0,,
底部:0
};
//按钮类组件
类按钮扩展了React.Component{
//返回函数
切换=事件=>{
返回此.props.toggle(事件);
};
//将侦听器附加到文档对象
handleDocumentClick=事件=>{
这个。切换(事件);
};
//将侦听器添加到文档对象
addEvents=()=>{
[“单击”,“触摸启动”]。forEach(事件=>
//事件从主体(根)元素传播到事件触发元素。
document.addEventListener(事件,this.handleDocumentClick,true)
);
};
//从文档对象中删除侦听器
removeEvents=()=>{
[“单击”,“触摸启动”]。forEach(事件=>
document.removeEventListener(事件,this.handleDocumentClick,true)
);
};
//当道具更改时添加或删除侦听器
manageProp=()=>{
如果(此.props.open){
这个。addEvents();
}否则{
这个.removeEvents();
}
};
componentDidMount(){
这是manageProp();
}
组件将卸载(){
警报(“按钮清理”);
这个.removeEvents();
}
componentDidUpdate(prevProps){
如果(this.props.open!==prevProps.open){
这是manageProp();
}
}
render(){
返回按钮;
}
}
//应用程序类组件
类应用程序扩展了React.Component{
状态={
开放:假
};
切换=()=>{
警报(“单击按钮”);
这是我的国家({
打开:!this.state.open
});
};
render(){
返回(
{/*基于类的按钮组件*/}
{/*背景*/}
{this.state.open&&}
);
}
}
//渲染它
render(,document.getElementById(“根”))

我已经对您的代码做了一些清理,但主要的一点是您必须存储
道具。在useffect钩子中使用它之前,在本地范围的常量中打开

import React, { useEffect } from "react";

const Button = props => {
  const isOpen = props.open;

  // Add event listeners
  const addEvents = () => {
    ["click", "touchstart"].forEach(event =>
      document.addEventListener(event, props.toggle, true)
    );
  };

  // Remove event listeners
  const removeEvents = () => {
    ["click", "touchstart"].forEach(event =>
      document.removeEventListener(event, props.toggle, true)
    );
  };

  // Mount, Unmount & DidUpdate
  useEffect(() => {
    // Add or remove listeners based on the state changes
    const manageProp = () => {
      if (isOpen) {
        addEvents();
      } else {
        removeEvents();
      }
    };
    // mount
    manageProp();
    // unmount
    return manageProp;
  }, [isOpen]);

  // Render it
  return <button onClick={props.toggle}>Button</button>;
};

export default Button;
import React,{useffect}来自“React”;
常量按钮=道具=>{
const isOpen=props.open;
//添加事件侦听器
常量addEvents=()=>{
[“单击”,“触摸启动”]。forEach(事件=>
document.addEventListener(事件,props.toggle,true)
);
};
//删除事件侦听器
常量removeEvents=()=>{
[“单击”,“触摸启动”]。forEach(事件=>
document.removeEventListener(事件,props.toggle,true)
);
};
//装载、卸载和更新
useffect(()=>{
//根据状态更改添加或删除侦听器
const manageProp=()=>{
if(等参线){
addEvents();
}否则{
移除事件();
}
};
//坐骑
manageProp();
//卸载
返回manageProp;
},[isOpen]);
//渲染它
返回按钮;
};
导出默认按钮;


每次依赖项发生更改时,从
useffect
返回的函数。在您的例子中,这种依赖关系是
props.open

当您从此函数调用
removeEvents
时,您将借助
props.open
为true添加两次事件。相反,您可以在每次道具更改时删除事件:

useEffect(() => {
    // Add or remove listeners based on the state changes
    const manageProp = () => {
      if (props.open) {
        addEvents();
      } else {
        removeEvents();
      }
    };
    // mount
    manageProp();
    // unmount
    return () => {
      removeEvents();
    };
  }, [props.open]);


只需将
addEvents
removeEvents
移动到
useffect
中,即可消除警告

Does
return()=>{removeEvents();}将不会执行?我认为它只会在组件卸载时工作。是的,它也会在组件卸载时执行,这也是PropThank中的一个变化。谢谢,为什么linter抱怨
React Hook useEffect缺少依赖项:“addEvents”和“removeEvents”。包括它们或删除依赖项数组。
linter查找
useffect
中使用的所有变量,它将
addEvents
removeEvents
视为两个可能会更改并导致应用程序出现错误的DEP。请参阅中的解释。您可以将它们移动到
useffect
中,也可以将它们添加到deps阵列中什么样的bug?你能给我一个干净的解决方案让我学习吗?