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
相关产品推荐
相关产品推荐

