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