页面刷新时Modal显示,点击About链接无响应的问题排查
问题描述
页面刷新时Modal可正常显示,但点击导航栏的About链接时,Modal无法弹出。怀疑和props传递有关,但不清楚具体错误点。
App.js 代码
function App() { const [showAboutModal, setShowAboutModal] = useState(false); const navLinkClicked = (selectedKey) => { if (selectedKey === 'about') { alert(showAboutModal) setShowAboutModal(true) } } return ( <div className="App"> <AboutModal showAboutModal={showAboutModal}/> <Navbar collapseOnSelect expand="lg" bg="light"> <Container> <img width="50" height="50" src={beacon} className="App-logo" alt="logo" /> <Navbar.Brand href="/">Title</Navbar.Brand> <Navbar.Toggle aria-controls="responsive-navbar-nav" /> <Navbar.Collapse id="responsive-navbar-nav"> <Nav className="me-auto"> </Nav> <Nav onSelect={(selectedKey) => navLinkClicked(selectedKey)}> <Nav.Link eventKey="about">About</Nav.Link> </Nav> </Navbar.Collapse> </Container> </Navbar> </div> ); } export default App;
AboutModal.js 代码
function AboutModal(showAboutModal) { const [showModal, setShowModal] = useState(showAboutModal); return ( <Modal show={showModal}> <Modal.Header> <Modal.Title>About</Modal.Title> </Modal.Header> <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body> <Modal.Footer> <Button variant="secondary" onClick={()=>setShowModal(false)}> Close </Button> </Modal.Footer> </Modal> ); } export default AboutModal;
问题分析与解决方案
你指出的const [showModal, setShowModal] = useState(showAboutModal);确实是问题核心,具体错误和修复方式如下:
错误点1:组件接收props的方式错误
React组件的参数是一个props对象,不是单个属性值。当前AboutModal直接把参数当作showAboutModal,实际拿到的是包含showAboutModal的对象,导致初始state值错误。
错误点2:本地state未同步父组件props更新
useState的初始值仅在组件挂载时生效一次。当父组件showAboutModal通过点击About链接变为true时,子组件的本地showModal不会自动更新,所以Modal不会弹出。
修复方案1:同步props到本地state
修改AboutModal.js,正确解构props并通过useEffect同步props变化:
import { useState, useEffect } from 'react'; function AboutModal({ showAboutModal }) { const [showModal, setShowModal] = useState(showAboutModal); // 当父组件props变化时,更新本地state useEffect(() => { setShowModal(showAboutModal); }, [showAboutModal]); return ( <Modal show={showModal}> <Modal.Header> <Modal.Title>About</Modal.Title> </Modal.Header> <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body> <Modal.Footer> <Button variant="secondary" onClick={()=>setShowModal(false)}> Close </Button> </Modal.Footer> </Modal> ); } export default AboutModal;
修复方案2:直接使用父组件props(更推荐)
如果不需要在子组件中独立控制Modal显示状态,完全可以直接使用父组件的props,去掉本地state,同时通过回调通知父组件关闭Modal:
修改AboutModal.js:
function AboutModal({ showAboutModal, onClose }) { return ( <Modal show={showAboutModal}> <Modal.Header> <Modal.Title>About</Modal.Title> </Modal.Header> <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body> <Modal.Footer> <Button variant="secondary" onClick={onClose}> Close </Button> </Modal.Footer> </Modal> ); } export default AboutModal;
修改App.js中Modal的调用:
<AboutModal showAboutModal={showAboutModal} onClose={() => setShowAboutModal(false)}/>
这样可以保证父子组件状态完全同步,避免状态不一致的问题。
内容的提问来源于stack exchange,提问作者Vishal
相关产品推荐
相关产品推荐

