ReactJS实现点击侧边栏按钮单弹窗显示隐藏的问题及解决
React 实现点击侧边栏按钮仅显示对应弹窗、隐藏其他弹窗
问题描述
刚接触ReactJS,正在开发Web项目,需求是点击侧边栏按钮时显示对应的Div弹窗,同时隐藏其他所有Div,所有Div默认隐藏。目前实现了点击按钮分别控制弹窗显示/隐藏,但存在问题:当一个弹窗已打开时点击另一个按钮,两个弹窗会同时显示互相覆盖,不符合需求。
初始代码
export default function LoginBox() { const [show, setShow] = useState(false); const [showControls, setShowControls] = useState(false); return ( <> <div id="sidebarLeft" className="hideBar"> <div className="leftBarDetails"> <div className="home topButton"> <div className="sideButtonIcon" onClick={()=>{setShow(!show)}} > <i className="fa-solid fa-user"></i> </div> </div> <div className="home topButton"> <div className="sideButtonIcon" onClick={()=>{setShowControls(!showControls)}}> <i className="fa-solid fa-gamepad"></i> </div> </div> </div> </div> {show && <div className="logincontainer hidden"> <label className="close-btn fas fa-times" onClick={()=>{setShow(!show)}}></label> <div className="text">Login Form</div> <form action="#"> <div className="data"> <label>Email</label> <input type="text" required /> </div> <div className="data"> <label>Password</label> <input type="password" required /> </div> <div className="forgot-pass"> <a href="#">Forgot Password?</a> </div> <div className="btn"> <div className="inner"></div> <button type="submit">login</button> </div> <div className="signup-link"> Need an account? <a href="#"> Signup now</a> </div> </form> </div>} {showControls && <div className="logincontainer hidden"> <label className="close-btn fas fa-times" onClick={()=>{setShowControls(!showControls)}}> </label> <div className="text"> <p> <b>CONTROLS</b> :<br /> <b>WASD || ARROW KEYS</b> - Move<br /> <b>R|F || SPACEBAR | SHIFT</b> - Up | Down<br /> </p></div> </div>} </> ); }
解决方案
通过优化状态管理逻辑,将独立的布尔状态合并为单一状态标记当前显示的弹窗,实现点击按钮时自动切换弹窗显示状态,确保同一时间仅显示一个弹窗。
import { useState } from "react"; export default function LoginBox() { const [show, setShow] = useState(''); const [sidebarActive, setSidebarActive] = useState(false); const handleClick = (id) => { if (show === id) { setShow(''); setSidebarActive(false); } else { setShow(id); setSidebarActive(true); } }; const handleParentClick = () => { if (sidebarActive) { setShow(''); setSidebarActive(false); } }; return ( <> <div id="sidebarLeft" className={`hideBar ${sidebarActive ? 'active' : ''}`}> <div className="leftBarDetails"> <div className="home topButton" onClick={() => handleClick('login')}> <div className="sideButtonIcon"> <i className="fa-solid fa-user"></i> </div> </div> <div className="home topButton" onClick={() => handleClick('controls')}> <div className="sideButtonIcon"> <i className="fa-solid fa-gamepad"></i> </div> </div> </div> </div> {show === 'login' && ( <div className="logincontainer hidden" onClick={handleParentClick}> <label className="close-btn fas fa-times" onClick={() => setShow('')}></label> <div className="text">Login Form</div> <form action="#"> <div className="data"> <label>Email</label> <input type="text" required /> </div> <div className="data"> <label>Password</label> <input type="password" required /> </div> <div className="forgot-pass"> <a href="#">Forgot Password?</a> </div> <div className="btn"> <div className="inner"></div> <button type="submit">login</button> </div> <div className="signup-link"> Need an account? <a href="#"> Signup now</a> </div> </form> </div> )} {show === 'controls' && ( <div className="logincontainer hidden" onClick={handleParentClick}> <label className="close-btn fas fa-times" onClick={() => setShow('')}></label> <div className="text"> <p> <b>CONTROLS</b>:<br /> <b>WASD || ARROW KEYS</b> - Move<br /> <b>R|F || SPACEBAR | SHIFT</b> - Up | Down<br /> <b>LEFT CLICK AND MOUSE</b> - Camera Movement<br /> <b>ESC</b> - Exit Camera Movement<br /> </p> </div> </div> )} </> ); }
核心优化点
- 合并状态:将原本两个独立的布尔状态替换为一个字符串状态
show,通过存储弹窗ID精准控制显示目标 - 统一交互:通过
handleClick函数处理所有按钮点击逻辑,自动判断是切换弹窗还是关闭弹窗,确保同一时间仅显示一个弹窗 - 增强体验:添加
handleParentClick实现点击弹窗区域(除关闭按钮外)关闭弹窗的交互
内容的提问来源于stack exchange,提问作者SecretFerret
相关产品推荐
相关产品推荐

