共享Popper切换需两次点击,如何实现单次点击切换?
解决Material-UI Popper切换项目需两次点击的问题
问题描述
我用Material-UI的Popper组件实现了运动项目内容展示,多个按钮共用一个Popper。但切换项目时必须点击两次:第一次关闭当前Popper,第二次才能打开新内容的Popper,体验很差。
解决方案
问题出在原handleClick的逻辑——每次点击都会先判断是否已有锚点,有就关闭,没有才打开。切换按钮时,第一次点击会关闭当前Popper,第二次才会打开新的。我们需要调整逻辑,直接判断点击的按钮是否是当前激活的锚点:
- 如果Popper未打开:点击按钮直接打开,同时切换内容
- 如果Popper已打开:
- 点击的是当前锚点按钮:关闭Popper
- 点击的是其他按钮:直接更新锚点和内容,保持Popper打开状态
修改后的完整代码如下:
import React, { useState } from 'react'; import { Popper, Button, Paper } from "@material-ui/core"; function CategoryMenuItemContent(props) { return ( <Paper style={{ padding: 16 }}> <p>{props.menu.label}</p> {props.menu.content} </Paper> ); } export default function App() { const baseballCategory = { label: 'Baseball', content: <p>棒球相关内容</p> }; const basketballCategory = { label: 'Basketball', content: <p>篮球相关内容</p> }; const footballCategory = { label: 'Football', content: <p>足球相关内容</p> }; const hockeyCategory = { label: 'Hockey', content: <p>曲棍球相关内容</p> }; const [activeCategory, setActiveCategory] = useState('baseball'); const categoryComponents = { "baseball": <CategoryMenuItemContent menu={baseballCategory} />, "basketball": <CategoryMenuItemContent menu={basketballCategory} />, "football": <CategoryMenuItemContent menu={footballCategory} />, "hockey": <CategoryMenuItemContent menu={hockeyCategory} />, }; const [anchorEl, setAnchorEl] = useState(null); const handleClick = (event) => { const targetCategory = event.currentTarget.textContent.toLowerCase(); // 判断当前点击的是否是已激活的锚点按钮 if (anchorEl === event.currentTarget) { // 点击的是当前打开Popper的按钮,关闭Popper setAnchorEl(null); } else { // 点击的是新按钮,直接更新锚点和内容,保持Popper打开 setAnchorEl(event.currentTarget); setActiveCategory(targetCategory); } }; const open = Boolean(anchorEl); const id = open ? 'simple-popper' : undefined; return ( <> <Button onClick={handleClick}>Baseball</Button> <Button onClick={handleClick}>Basketball</Button> <Button onClick={handleClick}>Football</Button> <Button onClick={handleClick}>Hockey</Button> <Popper id={id} open={open} anchorEl={anchorEl}> {categoryComponents[activeCategory]} </Popper> </> ); }
关键改动说明
- 重构
handleClick逻辑:直接对比当前点击元素与anchorEl,同一元素则关闭Popper,不同元素则直接更新锚点和内容,无需先关闭再打开 - 简化Popper内容渲染:通过
activeCategory直接取值,替代原代码中多个条件判断的写法 - 新增
Paper组件包裹内容(可选):提升Popper的视觉层级和美观度
修改后,点击不同按钮即可单次完成Popper内容切换,点击当前激活按钮则关闭Popper,完全符合预期需求。
内容的提问来源于stack exchange,提问作者PhoenixDown
相关产品推荐
相关产品推荐

