React中如何使用路由实现弹窗内部到下一个弹窗视图的跳转?
问题原因
- 重复声明
<Router>:整个React应用仅需要1个全局Router即可,你在业务App、弹窗组件中都定义了Router,导致路由上下文相互隔离,导航无法生效 - Switch组件用法错误:Switch仅支持包裹
Route/Redirect组件,你直接将Link放在Switch内部,会导致路由匹配逻辑失效 - 第二弹窗的返回按钮未配置跳转逻辑,无法触发路由切换
- 未配置弹窗初始路由的匹配规则,打开弹窗后默认视图无法正常加载
解决方案
方案1:使用全局路由(会修改浏览器地址栏)
第一步:移除冗余Router声明
删除业务App.js、弹窗组件内的所有<Router>标签,仅保留项目入口文件(通常为src/index.js)中的全局Router配置。
第二步:修改弹窗组件代码
import styled from "styled-components"; import { Link as LinkR, Switch, Route } from "react-router-dom"; export const NavBtn = styled(LinkR)` `; // 弹窗第一视图组件 function FirstPopupView() { return ( <div> <LogoWrap> <LogoBtn> <LogoText>Welcome to the first popup view</LogoText> </LogoBtn> </LogoWrap> <hr /> <NavBtn to="/PopupSecondView"> <NavBtnLink>Next window</NavBtnLink> </NavBtn> </div> ) } export default function Popup(props) { return ( <div className="ms-welcome"> <Switch> <Route exact path="/" component={FirstPopupView} /> <Route path="/PopupSecondView" component={SecondView} /> </Switch> </div> ); }
第三步:修改第二弹窗视图代码
import { Link } from "react-router-dom"; export default function SecondView(props) { return ( <div> <LogoWrap> <LogoBtn> <LogoText>Welcome to the second view</LogoText> </LogoBtn> </LogoWrap> <hr /> <Link to="/"> <NavBtnLink>Previous window</NavBtnLink> </Link> </div> ); }
第四步:修改业务App.js代码
import { useState } from "react"; import Popup from './Popup' // 导入你的弹窗组件 export default function App(props) { const [showPopup, setShowPopup] = useState(false) const click = () => setShowPopup(true) return ( <div className="ms-welcome"> <LogoWrap> <LogoBtn> <AiFillHome /> <LogoText>Virta</LogoText> </LogoBtn> <LogoBtn> <AiOutlineInfoCircle /> <LogoText>Info</LogoText> </LogoBtn> <LogoBtn> <VscRefresh /> <LogoText>Update</LogoText> </LogoBtn> </LogoWrap> <Button className="ms-welcome__action" buttonType={ButtonType.hero} iconProps={{ iconName: "ChevronRight" }} onClick={click} > Open popup dialog window demo </Button> <hr /> {showPopup && <Popup />} </div> ); }
方案2:使用MemoryRouter(弹窗内部路由独立,不修改全局地址栏)
如果不希望弹窗导航影响浏览器地址,也不想和全局路由冲突,直接用MemoryRouter包裹弹窗组件即可,无需修改全局路由配置:
import styled from "styled-components"; import { Link as LinkR, Switch, Route, MemoryRouter } from "react-router-dom"; export const NavBtn = styled(LinkR)` `; function FirstPopupView() { return ( <div> <LogoWrap> <LogoBtn> <LogoText>Welcome to the first popup view</LogoText> </LogoBtn> </LogoWrap> <hr /> <NavBtn to="/PopupSecondView"> <NavBtnLink>Next window</NavBtnLink> </NavBtn> </div> ) } function SecondView() { return ( <div> <LogoWrap> <LogoBtn> <LogoText>Welcome to the second view</LogoText> </LogoBtn> </LogoWrap> <hr /> <Link to="/"> <NavBtnLink>Previous window</NavBtnLink> </Link> </div> ); } export default function Popup(props) { return ( <MemoryRouter initialEntries={['/']}> <div className="ms-welcome"> <Switch> <Route exact path="/" component={FirstPopupView} /> <Route path="/PopupSecondView" component={SecondView} /> </Switch> </div> </MemoryRouter> ); }
内容的提问来源于stack exchange,提问作者edwin
相关产品推荐
相关产品推荐

