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

React实现关闭Navbar Dropdown时卸载组件的方法

实现React-Bootstrap下拉菜单关闭时卸载子组件,重新打开时重新请求数据

问题说明

我使用如下React-Bootstrap导航栏:

<Navbar bg="dark" variant="dark" expand="lg" className="navbar">
  <Container>
    <Navbar.Brand className="edowl-title small-scale"> <Link to="/">title</Link></Navbar.Brand>
    <Navbar.Toggle aria-controls="responsive-navbar-nav" />
    <Navbar.Collapse id="responsive-navbar-nav">
      <Nav className="me-auto">
        <NavDropdown className="Main-element tiny-scale" title="Updates" id="basic-nav-dropdown">
          <Updates/>
        </NavDropdown>
        <NavDropdown className="Main-element tiny-scale" title="Notes" id="basic-nav-dropdown">
          <QuickNotes/>
        </NavDropdown>
      </Nav>
    </Navbar.Collapse>
  </Container>
</Navbar>

<Updates/>组件在挂载时会发起请求获取更新数据:

const [updates, setUpdates] = useState([])
const [{ tokens }, dispatch] = useStateValue();
const[errorMsg, setErrorMsg] = useState(false);

useEffect(() => {
    const loadUpdates = async () => {
        try {
            const post_request = await Axios({
                method: "get",
                url: `${window.ipAddress.ip}/Update/Recent`,
                headers: { "Content-Type": "application/json", "Authorization": `Bearer ${tokens.access_token}` }
            })

            console.log(post_request)
            if (post_request.status === 200) {
                setUpdates(post_request.data)
            }
            else { setErrorMsg("Couldnt complete") }
        }
        catch (err) {
            if (err) {
                setErrorMsg(err)
            }
        }
    }
    loadUpdates();
}, [])

useEffect(() => {
    if (updates.length <= 0) {
        var todayDate = new Date();
        var todayDateText = todayDate.getDate() + "/" + (todayDate.getMonth() + 1) + "/" + todayDate.getFullYear()

        console.log(todayDateText);
        setUpdates([{ content: "There is currently no new updates", generatedDate: todayDateText, id: 1 }])
    }
},[updates])

return (
    <div className="update-container">
        <ul className="update-list">
            {updates.map((update, index) => (
                <li key={index} className="update-element"><p>{update?.generatedDate} - {update?.content}</p></li>
            ))}
        </ul>
    </div>
);

由于请求仅在组件挂载时执行,关闭下拉菜单后重新打开,不会再次发起请求。需要实现关闭Navbar Dropdown时卸载<Updates/>组件,使其重新打开时重新挂载并执行请求。

解决方案

核心思路是通过条件渲染控制子组件的挂载状态,结合NavDropdown的onToggle事件跟踪菜单展开/收起状态,仅在菜单展开时渲染<Updates/>,收起时销毁组件,从而实现重新打开时的重新挂载与请求。

步骤1:在父组件中添加状态跟踪下拉菜单状态

在导航栏所在的父组件中,声明状态变量记录Updates下拉菜单的展开状态:

import { useState } from 'react';

// ... 其他代码
const [isUpdatesDropdownOpen, setIsUpdatesDropdownOpen] = useState(false);

步骤2:给NavDropdown绑定onToggle事件并条件渲染子组件

修改Updates对应的NavDropdown,添加onToggle事件更新状态,并仅在菜单展开时渲染<Updates/>:

<NavDropdown
  className="Main-element tiny-scale"
  title="Updates"
  id="basic-nav-dropdown"
  onToggle={(isOpen) => setIsUpdatesDropdownOpen(isOpen)}
>
  {/* 仅当菜单展开时渲染Updates组件,收起时自动卸载 */}
  {isUpdatesDropdownOpen && <Updates />}
</NavDropdown>

可选优化:更新Updates组件的useEffect依赖项

如果需要在tokens.access_token变化时也能重新请求数据,可以给useEffect添加依赖项:

useEffect(() => {
    const loadUpdates = async () => {
        // ... 原有请求逻辑
    }
    loadUpdates();
}, [tokens.access_token]) // 添加tokens.access_token作为依赖

这样设置后,每次打开Updates下拉菜单时,<Updates/>都会重新挂载并执行请求,确保获取最新的更新数据。

内容的提问来源于stack exchange,提问作者ABpositive

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:33:27