Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.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 根据使用中的prevState有条件地设置状态会导致指数重新渲染_Reactjs - Fatal编程技术网

Reactjs 根据使用中的prevState有条件地设置状态会导致指数重新渲染

Reactjs 根据使用中的prevState有条件地设置状态会导致指数重新渲染,reactjs,Reactjs,带有useEffect挂钩的简单功能性有状态组件。其主要目的是根据event.target等于ref.current来侦听单击并切换配置文件菜单 e.target === ref.current 但是,如果我添加 && !menuVisible 对于该条件(仅当其隐藏时显示菜单),每次单击都会导致指数级重新渲染。从一次单击一次渲染开始,第二次单击两次渲染,第三次单击四次渲染,第四次单击八次渲染 const Profile: React.FC = () => { co

带有useEffect挂钩的简单功能性有状态组件。其主要目的是根据event.target等于ref.current来侦听单击并切换配置文件菜单

e.target === ref.current
但是,如果我添加

&& !menuVisible
对于该条件(仅当其隐藏时显示菜单),每次单击都会导致指数级重新渲染。从一次单击一次渲染开始,第二次单击两次渲染,第三次单击四次渲染,第四次单击八次渲染

const Profile: React.FC = () => {
  const ref = useRef<HTMLDivElement | null>(null);
  const [menuVisible, setMenuVisible] = useState(false);

  useEffect(() => {
    const handleClick = (e: Event) => {
      e.target === ref.current && !menuVisible
        ? setMenuVisible(true)
        : setMenuVisible(false);
    };
    window.addEventListener("click", e => handleClick(e));
    return () => {
      window.removeEventListener("click", e => handleClick(e));
    };
  });

  return (
    <ProfileWrapper>
      <ProfileMedailone ref={ref} />
      {menuVisible && <ProfileMenu />}
    </ProfileWrapper>
  );
};
const Profile:React.FC=()=>{
const ref=useRef(null);
常量[menuVisible,setMenuVisible]=useState(false);
useffect(()=>{
常量handleClick=(e:Event)=>{
e、 目标===ref.current&!菜单可见
?设置菜单可见(真)
:setMenuVisible(假);
};
addEventListener(“单击”,e=>handleClick(e));
return()=>{
removeEventListener(“单击”,e=>handleClick(e));
};
});
返回(
{menuVisible&&}
);
};

我应该在清理阶段做得更好吗?或者捕获点在哪里?

1。)向
useffect()
2]添加一个空的依赖项数组。将单击事件更改为
const handleClick=(e:event)=>{if(e.target==ref.current)setMenuVisible(current=>!current);}3。)删除add/removeEventListeners中的匿名函数,然后按方法传入
handleClick
。谢谢您,先生!我刚刚保留了else语句
target!==当单击位于其他任何位置时,请参考当前设置菜单可见(false)
,以隐藏菜单。但是你的评论解决了我的问题。@David Zoufaly你能在这里添加你的最终代码和工作代码作为答案吗?会很有帮助的!
   useEffect(() => {
    const handleClick = (e: Event) => {
      if (e.target === ref.current) {
        setMenuVisible(current => !current);
      } else if (
        e.target === ref2.current ||
        e.target === ref2.current?.children[1] ||
        e.target === ref2.current?.children[2]
      ) {
        setMenuVisible(true);
      } else {
        setMenuVisible(false);
      }
    };
    window.addEventListener("click", handleClick);
    return () => {
      window.removeEventListener("click", handleClick);
    };
  }, []);