You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:53:08