父组件已包裹Router时子组件Signup为何仍需再次包裹Router
问题原因
你遇到的现象不是React Router的设计要求,本质是你的代码写法不规范导致路由上下文传递断裂,额外包裹Router只是歪打正着解决了上下文缺失的问题,属于错误的修复方式。
- 直接原因:
<Redirect>、<Switch>、<Route>这类路由组件,必须在Router提供的路由上下文环境中才能运行,你移除SignUp里的Router后页面空白,100%可以在控制台看到You should not use <Route> outside a <Router>这类报错,渲染被错误打断才导致页面空白。 - 为什么上层已经包裹了Router,子组件还是拿不到上下文?问题出在你的
App.js写法不规范:- 你在App组件中额外套了一层无任何属性的
<Route>,并且把逻辑直接写在 之外,这种写法不符合React Router v5的使用规范,导致路由上下文无法正确向下传递给SignUp组件。 - 你额外在SignUp里包裹同history的Router,等于给SignUp内部的路由组件单独提供了可用的路由上下文,所以不再报错,但这种写法会引入两个独立的Router实例(哪怕history相同),后续容易出现路由不同步的隐性bug。
- 你在App组件中额外套了一层无任何属性的
正确修复方案
你不需要在SignUp里重复包裹Router,只要修改App.js的写法即可:
// 修正后的App.js代码 return ( <div className='App-div'> <Switch> {/* 把根路径重定向逻辑放到Switch最前面 */} <Route exact path="/"> {signUpFirst ? <Redirect to='/signup' /> : <Redirect to='/home' />} </Route> <Route exact path='/signup'> <SignUp homePage={exitSignUpPage} setUserNumber={setUserID} /> </Route> <Route exact path='/home'> <Home userIDNumber={userID} /> </Route> </Switch> </div> );
修改后删除SignUp.js里的Router包裹代码即可正常运行。
内容的提问来源于stack exchange,提问作者ExtraSun
相关产品推荐
相关产品推荐

