React Router@4.2.0中Switch渲染组件异常及路由配置问题求助
嘿,完全不用避开<Switch>组件,它其实正是解决你当前路由冲突的关键!反而应该好好利用它来解决不必要的组件渲染问题。
问题出在哪?
在React Router v4里,<Route>默认是前缀匹配,不是精确匹配。也就是说,当你访问/locations/new时,不仅会命中/locations/new的路由,还会命中所有以/locations开头的路由——比如你用来渲染CityList的那个/locations路由。这就导致CityList被意外渲染了,但此时它需要的props可能没正确传入,自然就触发PropTypes报错了。
你之前加exact导致其他路由显示null,大概率是把exact加错地方了——比如给主路由里的/locations加了exact,那/locations/new就匹配不到这个主路由了,内部的子路由组件自然就显示null了。
正确的配置方式
我们要在合适的层级用上<Switch>,让它只渲染第一个匹配的路由,再配合exact的正确使用:
第一步:主路由层的配置
假设你的主路由结构是这样的,在外层用<Switch>,而且给/locations的路由不要加exact——这样它才能匹配所有/locations开头的子路径:
import { Switch, Route } from 'react-router-dom'; function App() { return ( <Switch> {/* 先放其他业务路由 */} <Route path="/locations" component={LocationsWrapper} /> {/* 404路由一定要放在最后,兜底用 */} <Route component={NotFound} /> </Switch> ); }
第二步:LocationsWrapper内部的子路由配置
在LocationsWrapper里,同样用<Switch>包裹子路由,这样只会渲染第一个匹配的组件:
import { Switch, Route } from 'react-router-dom'; function LocationsWrapper() { return ( <div> {/* 这里可以放Locations模块的公共导航、头部之类的布局 */} <Switch> {/* 划重点:把更具体的路由放在前面! */} <Route path="/locations/new" component={NewLocation} /> {/* 只给基础的列表路由加exact,确保只有访问/locations时才渲染CityList */} <Route exact path="/locations" component={CityList} /> </Switch> </div> ); }
几个核心注意点
<Switch>的核心作用:它会挨个检查子路由,只渲染第一个匹配当前URL的路由,彻底避免多个路由同时渲染的问题。- 路由顺序很重要:在
<Switch>里,一定要把更具体的路由放在前面(比如/locations/new要在/locations之前),不然/locations会先被匹配到,/locations/new就永远没机会渲染了。 exact别乱用:只给最基础的列表路由(/locations)加exact就够了,子路由(/locations/new)不需要,因为它本身比父路径更具体,在Switch里会被优先匹配。
这样配置之后,访问/locations会正常渲染CityList,访问/locations/new只会渲染NewLocation组件,不会再触发CityList的PropTypes错误,其他路由也能正常显示啦。
内容的提问来源于stack exchange,提问作者Tom Hanson

