一. Switch 、Router 、Route三者的区别
1、Route
Route 是建立location 和 ui的最直接联系
2、Router
react-router v4 中,Router被拆分成了StaticRouter、MemoryRouter、BrowserRouter、HashRouter、NativeRouter。
MemoryRouter、BrowserRouter、HashRouter 等于
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import { Router } from
'react-router'
<!--这里可以有三种-->
<!--history 部分源码
exports.createBrowserHistory = _createBrowserHistory3.
default
;
exports.createHashHistory = _createHashHistory3.
default
;
exports.createMemoryHistory = _createMemoryHistory3.
default
;
-->
import createBrowserHistory from
'history/createBrowserHistory'
//
const history = createBrowserHistory()
<Router history={history}>
<App/>
</Router>
|
NativeRouter(给rn使用的)
A <Router> for iOS and Android apps built using React Native.
这里新增strict 和 exact
使用了strict location 大于等于path才能匹配,eq path='/one' location='/one/a'能匹配。
使用了exact location 约等于 path 才能匹配,eq path='/one' location='/one'或者 '/one/'能匹配,所以说是约等于。
使用了exact 和 strict location = path才能匹配
StaticRouter(后续补充)
3、Switch
这是v4版本中新添加,主要用来做唯一匹配的功能。就是想要在众多路由中只匹配其中一个路由。
二、v4 版本中路由应该如何配置呢?
1.基本配置(这个和v3中基本一致,效果也基本一样)
匹配 <= location eq.( /b => / + /b ) ( / => / )
1
2
3
4
5
6
|
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<div>
<Route path=
"/"
component={aContainer} />
<Route path=
"/b"
component={bContainer} />
</div>
</BrowserRouter>
|
2.含Switch 配置
匹配 <= location eq.( /b => /b ) ( / => / ) 唯一匹配
1
2
3
4
5
6
7
|
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<Switch>
//这里用exact,仅仅是担心location被 path='/'截胡了。
<Route exact path=
"/"
component={aContainer} />
<Route path=
"/b"
component={bContainer} />
</Switch>
</BrowserRouter>
|
问题(三个问题)
1.如何设置公共的Component
第一种方式
1
2
3
4
5
6
|
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<div>
<Route path=
"/"
component={aContainer} />
<Route path=
"/b"
component={bContainer} />
</div>
</BrowserRouter>
|
第二种方式(父子嵌套)
1
2
3
4
5
6
7
|
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<div >
<Route path=
"/"
component={aContainer} />
<Route path=
"/b"
component={Parent} />
{
/* {app()} */
}
</div>
</BrowserRouter>
|
1
2
3
4
5
6
7
|
const Parent = ({ match }) => (
<div>
<Route path={`${match.url}/`} component={bContainer} />
<Route path={`${match.url}/c`} component={cContainer} />
<Route path={`${match.url}/d`} component={dContainer} />
</div>
);
|
这种情况 bContainer就是是公用的Component
2.如何设置getComponent,按需加载
3.是否有简化写法
1
|
npm
install
--save react-router-config
|
第一步 配置路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
const routes = [
{ component: bContainer,
routes: [
{ path:
'/'
,
exact:
true
,
component: bContainer
},
{ path:
'/b/b'
,
component: bContainer,
routes: [
{ path:
'/b/b/b'
,
component: bContainer
}
]
}
]
}
]
|
第二步 设置路由
1
2
3
4
5
|
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<div >
{renderRoutes(routes)}
</div>
</BrowserRouter>
|
第三步 需要在container的render中去调用方法
1
2
3
4
|
<div>
1111
{renderRoutes(
this
.props.route.routes)}
</div>
|
这个优势是可以统一配置,劣势是需要在container中统一调用,但是这个抽出来统一实现,问题也不大,并且还可以解决 问题一。
这个renderRoutes实际是就是用一层Switch和多个Route来包了一层。