React Hooks实现导航箭头展开/折叠子菜单:首次点击正常、后续点击失效问题求助
问题排查与修复方案
嘿,我一眼就看到你代码里几个关键问题,这正是导致后续点击失效的根源:
1. 错误的状态判断直接阻断函数执行
你函数开头的if (arrowIsClicked) return;完全把后续点击的路堵死了。第一次点击时,你先把arrowIsClicked设为true,后面又设回false,但React的状态更新是异步的——第二次点击时,这个判断会先拿到true的值,直接return,函数根本不会往下执行任何逻辑。
2. 提前的return语句让核心逻辑永远跑不起来
看你条件分支里的代码:
if (!e.target) console.log(e.target); return const parent = (e.target as HTMLElement).parentNode;
这里不管e.target是否存在,执行完console.log后都会立刻return!后面获取父节点、兄弟节点的代码完全没机会运行,自然也看不到你那句"function has almost done executing"的日志了。
3. 直接操作DOM不符合React设计思路
React的核心是用状态驱动UI,直接修改DOM元素的style不仅容易出问题,也不利于维护。我们应该用状态来控制箭头的旋转和子菜单的显示/隐藏。
修复后的完整代码
我帮你重构了代码,用状态管理UI变化,去掉了所有直接操作DOM的逻辑,同时修复了return的问题:
const ServiceConditions = () => { // 用单一状态控制菜单展开/折叠状态 const [isMenuExpanded, setIsMenuExpanded] = React.useState(false); const handleSublinksExpandCollapse = () => { // 直接切换状态,无需复杂DOM判断 setIsMenuExpanded(prev => !prev); } return ( <Container> { isDesktop && <> <NavigationContainer> <StyledScrollSpy scrollTargetIds={["section_1", "section_2", "section_3"]} offset={100} activeNavClass="is-active" scrollDuration="1000" headerBackground="true" > <List> <MainRef> <Line1> <MainRefTypography variant="body1"><a href="#">Home</a></MainRefTypography> {/* 用状态控制箭头旋转样式 */} <IconStyled id="ad-ap" onClick={handleSublinksExpandCollapse} style={{ transform: isMenuExpanded ? "rotate(180deg)" : "rotate(0deg)" }} ></IconStyled> </Line1> {/* 用状态控制子菜单显示/隐藏 */} <div style={{ display: isMenuExpanded ? "block" : "none" }}> <LinksInsideList> <MainRef><LinkInsideTypography variant="body4"><a href="#section_1">Section 1</a></LinkInsideTypography></MainRef> <MainRef><LinkInsideTypography variant="body4"><a href="#section_2">Section 2</a></LinkInsideTypography></MainRef> <MainRef><LinkInsideTypography variant="body4"><a href="#section_3">Section 3</a></LinkInsideTypography></MainRef> </LinksInsideList> </div> </MainRef> </List> </StyledScrollSpy> </NavigationContainer> </> } <Articles> <PageName variant={isDesktop ? "h3" : "h1"}>SERVICE CONDITIONS</PageName> <Bar align={BarAlign.Left} /> <Spacing mobile={3} desktop={3}/> <div style={{"height": "400px", width: "100%"}}><span>Welcome!</span></div> <div id="section_1" style={{"height": "500px", width: "100%"}}><span>Section 1</span></div> <div id="section_2" style={{"height": "500px", width: "100%"}}><span>Section 2</span></div> <div id="section_3" style={{"height": "500px", width: "100%"}}><span>Section 3</span></div> </Articles> </Container> ); }; export default ServiceConditions;
关键改进点说明
- 用
isMenuExpanded单一状态管理菜单状态,逻辑更清晰,避免状态混乱。 - 点击事件直接切换状态,React会自动根据状态更新UI,无需手动判断DOM样式。
- 去掉了所有多余的return语句,确保核心逻辑能正常执行。
- 完全遵循React状态驱动UI的理念,代码更易维护和调试。
这样修改后,你点击箭头就能正常切换菜单状态和箭头方向,再也不会出现后续点击无效的问题~
内容的提问来源于stack exchange,提问作者Lorasia Andrikanych
相关产品推荐
相关产品推荐

