如何解决React-Router-dom与Context API状态冲突导致404重定向失效问题
问题根本原因
React Router v5 的 <Switch> 组件核心逻辑是仅遍历直接子元素,匹配到第一个符合路径的 <Route>/<Redirect> 就渲染,非这两类的直接子元素会被无条件渲染。你将 <GlobalState> 直接作为 <Switch> 的直接子元素,不管当前路径是否匹配内部的 /dashboard 等路由,<GlobalState> 都会被直接渲染,之后的 <Redirect to="/404"/> 永远不会被执行,这就是访问未定义路由时白屏的核心原因。
可落地解决方案
方案1:给状态Provider包裹的路由组加统一父路径
给需要用到 GlobalState 的路由统一加前缀(比如 /app),外层套一个不带 exact 的 <Route> 匹配该前缀,GlobalState 写在这个Route的内部,只有路径匹配前缀时才会渲染Provider和内部路由,不匹配就会继续执行后面的404重定向逻辑。
return ( <Router> <Fragment> <Switch> <Route path='/' exact component={Home} /> <Route path='/signin' exact component={SignIn} /> <Route path='/restpassword' exact component={RestPassword} /> <Route path='/signup' exact component={SignUp} /> <Route path='/404' exact component={NotFound} /> {/* 匹配所有需要GlobalState的路由前缀 */} <Route path="/app"> <GlobalState> <Switch> <Route path='/app/dashboard' exact component={Dashboard} /> <Route path='/app/informationA' exact render={() => ( <FirstState> <InformationA /> </FirstState> )}/> <Route path='/app/informationB' exact render={() => ( <SecondState> <InformationB /> </SecondState> )}/> <Route path='/app/settings' exact component={Settings} /> </Switch> </GlobalState> </Route> <Redirect to='/404' /> </Switch> </Fragment> </Router> );
方案2:不修改现有路由路径,单独给每个需要状态的路由套Provider
如果不想调整现有路由路径,就不要把 GlobalState 直接放在Switch的直接子层级,每个需要对应状态的Route单独用render属性包裹对应的Provider即可,保证Switch的直接子元素只有Route和Redirect,路由匹配逻辑就能正常执行。
return ( <Router> <Fragment> <Switch> <Route path='/' exact component={Home} /> <Route path='/signin' exact component={SignIn} /> <Route path='/restpassword' exact component={RestPassword} /> <Route path='/signup' exact component={SignUp} /> <Route path='/404' exact component={NotFound} /> {/* 每个需要状态的路由单独包裹对应Provider */} <Route path='/dashboard' exact render={props => ( <GlobalState> <Dashboard {...props} /> </GlobalState> )}/> <Route path='/informationA' exact render={props => ( <GlobalState> <FirstState> <InformationA {...props} /> </FirstState> </GlobalState> )}/> <Route path='/informationB' exact render={props => ( <GlobalState> <SecondState> <InformationB {...props} /> </SecondState> </GlobalState> )}/> <Route path='/settings' exact render={props => ( <GlobalState> <Settings {...props} /> </GlobalState> )}/> <Redirect to='/404' /> </Switch> </Fragment> </Router> );
注:你原代码中路由路径的拼写错误
inofrmation可修正为information,避免出现路径匹配异常。
内容的提问来源于stack exchange,提问作者Richardson
相关产品推荐
相关产品推荐

