因为公司的需要最近踏进了react坑,一直在挖坑填坑,在路由这一块折腾得不行。
直接进入主题,配置react-router模块化
- 1.先下载react-router-dom
npm install react-router-dom --save
- 2.在相应的文件引入react-router-dom相应的模块
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
- 3.在src子创建一个module目录,接着在module目录在创建一个router.js文件,用来配置路由。
//router.js
import Index from '../components/Index'
import New from '../components/New'
import NewList from '../components/NewList'
import NewContent from '../components/NewContent'
const routes = [
{
path:"/",
component:Index,
exact:true
},
{
path:"/new",
component:New,
routes:[
{
path:"/new/",
component:NewContent
},
{
path:"/new/newList",
component:NewList
}
]
},
]
export default routes
- 4.在app.js根目录添加相应的跳转路径。
//app.js
import React from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import router from "./modules/routers"
function App() {
return (
<Router>
<nav className="nav">
<ul>
<li>
<Link to="/">首页</Link>
</li>
<li>
<Link to="/new">新闻</Link>
</li>
</ul>
</nav>
{
router.map((router,index)=>{
if(router.exact){
return <Route exact key={index} path={router.path}
render = {
props =>(
<router.component {...props} routes = {router.routes}/>
)
}
/>
}else{
return <Route key={index} path={router.path}
render = {
props =>(
<router.component {...props} routes = {router.routes} />
)
}
/>
}
})
}
</Router>
);
}
export default App;
注意点:嵌套路由千万不要在<Route/>身上加上component={xxx.xxx},否则在子路由页码就接受不到父路由传递给子路由的数据,重要的事情说三篇
注意点:嵌套路由千万不要在<Route/>身上加上component={xxx.xxx},否则在子路由页码就接受不到父路由传递给子路由的数据,重要的事情说三篇
注意点:嵌套路由千万不要在<Route/>身上加上component={xxx.xxx},否则在子路由页码就接受不到父路由传递给子路由的数据,重要的事情说三篇
解析一下,<Route/>里面的render,这是官方给出的一种固定写法,为了解决父路由传递数据给子路由接受不到的问题。render是一个对象,里面是一个箭头函数,箭头函数放回<router.component {...props} routes = {router.routes} />一个标签,router.component的router对于的是你map传进来的那个形参,传啥写啥;component 是配置文件对应的component ,routes 是传给子路由的数据、(子路由通过this.props.routes 接收)
- 5.在有子路由的页码配置跳转
import React ,{Component} from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
class New extends Component{
render(){
return(
<div className="box">
<div className="left">
<ul>
<li>
<Link to="/new">New</Link>
</li>
<li>
<Link to="/new/newList">NewList</Link>
</li>
</ul>
</div>
<div className="right">
{
this.props.routes.map((item,index)=>{
return <Route key={index} exact path={item.path} component={item.component}></Route>
})
}
</div>
</div>
)
}
}
export default New
一. Switch 、Router 、Route三者的区别
1、Route
Route 是建立location 和 ui的最直接联系
2、Router
react-router v4 中,Router被拆分成了StaticRouter、MemoryRouter、BrowserRouter、HashRouter、NativeRouter。
MemoryRouter、BrowserRouter、HashRouter 等于
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 ) ( / => / )
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<div>
<Route path="/" component={aContainer} />
<Route path="/b" component={bContainer} />
</div>
</BrowserRouter>
2.含Switch 配置
匹配 <= location eq.( /b => /b ) ( / => / ) 唯一匹配
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<Switch>
//这里用exact,仅仅是担心location被 path='/'截胡了。
<Route exact path="/" component={aContainer} />
<Route path="/b" component={bContainer} />
</Switch>
</BrowserRouter>
问题(三个问题)
1.如何设置公共的Component
第一种方式
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<div>
<Route path="/" component={aContainer} />
<Route path="/b" component={bContainer} />
</div>
</BrowserRouter>
第二种方式(父子嵌套)
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<div >
<Route path="/" component={aContainer} />
<Route path="/b" component={Parent} />
{/* {app()} */}
</div>
</BrowserRouter>
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.是否有简化写法
npm install --save react-router-config
第一步 配置路由
const routes = [
{ component: bContainer,
routes: [
{ path: '/',
exact: true,
component: bContainer
},
{ path: '/b/b',
component: bContainer,
routes: [
{ path: '/b/b/b',
component: bContainer
}
]
}
]
}
]
第二步 设置路由
<BrowserRouter forceRefresh={!supportsHistory} keyLength={12}>
<div >
{renderRoutes(routes)}
</div>
</BrowserRouter>
第三步 需要在container的render中去调用方法
<div>
1111
{renderRoutes(this.props.route.routes)}
</div>
这个优势是可以统一配置,劣势是需要在container中统一调用,但是这个抽出来统一实现,问题也不大,并且还可以解决 问题一。
网友评论