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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:07:40