声明:此处的动态与静态专指前端应用的开发领域。javascript
路由是一种URL到页面的映射关系.html
静态路由须要开发者考虑两层:前端
静态路由提早声明,简单易懂,Vue-router就是静态路由的例子。java
动态路由相反,将上述两层关注合为一体:页面设计开发过程直接确立了URL与组件的关系,开发的样子,决定了路由的样子,符合了动态的理念。开发者无需额外管理与配置路径。省心省力。react
react-router v4采用了动态路由(react有一个静态路由包在内测中
),以前版本则是静态路由,。 须要注意的是,react-router v4里,route也是一种组件的存在形式.git
//static routes
const routes = [
{
component: Root,
routes: [
{
path: "/",
exact: true,
component: Home
},
{
path: "/child/:id",
component: Child,
routes: [
{
path: "/child/:id/grand-child",
component: GrandChild
}
]
}
]
}
];
//dynamic routes
const App = () => (
<Router>
<div>
<Header />
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
</div>
</Router>
);
export default App;
复制代码
到react-router的github官网看到这一句:github
we actually publish several packages to npm from the same codebase. 同一个代码基项目发布了几个包:web
核心包
,其余包依赖该包web项目
使用react-router-dom,开发原生应用
使用react-router-native静态路由
版本react-router-config,目前内测阶段所以咱们只须要关注react-router-dom便可。express
react-router-dom教程网上不少,在此咱们罗列几个比较重要或易错的概念,若是须要详细内容,请至:官方API。npm
有两种路由类型:browserRouter、HashRouter
// <BrowserRouter>
http://example.com/about
// <HashRouter>
http://example.com/#/about
复制代码
前者使用 HTML5 History API 来跟踪路由变化。后者使用window.location.hash做为记录跟踪方式 。
前者新颖美观,须要服务端的额外支持,原理就是拦截前端的路径请求(非功能请求),响应同一个index.html,而后浏览器会根据根据路径渲染相应的视图或页面。举个express的例子:
const express = require('express');
const path = require('path');
const port = process.env.PORT || 8080;
const app = express();
//加载静态资源,dist下放build好的文件
app.use(express.static(__dirname + '/dist'))
//非功能请求统一转到index.html
//index.html及其对应的js文件会根据React-Router规则匹配对应route
app.get('*', function (request, response){
response.sendFile(path.resolve(__dirname, 'dist', 'index.html'))
})
app.listen(port, function () {
console.log("server started on port " + port)
})
复制代码
后者简单兼容性好,不须要额外配置服务端。 须要指出的是:rowserRouter或 HashRouter必须位于路由相关组件的最外层
,此处的相关组件经常使用的有:Link、Route、Switch、Redirect
<Link to/>
标签,或<a href="#"></a>
标签,或<Redirect to/>
push(path)、replace(path)、go(n) 、goBack() 、 goForward()
都是经过Route组件
这座桥梁实施的,但有多种实施方式render、component、children
很差理解?代码演示对比下
function fnComponent(){
return <div>我是个具名函数组件</div>
}
class classComponent extends Component{
render(){
<div>我是个class组件</div> } } //render只能为函数组件 <Route path="/render" render={()=>{<div>我是个匿名/行内函数组件</div>}}/>
<Route path="/render" render={fnComponent}/>
//children能够为函数组件、也但是jsx对象
<Route path="/children" children={()=>{<div>我是个匿名/行内函数组件</div>}}/>
<Route path="/children" children={fnComponent}/>
<Route path="/children" children={<div>我是一条jsx语法标签对象</div>}/>
//component只能为函数组件或class组件
<Route path="/children" component={()=>{<div>我是个匿名/行内函数组件</div>}}/>
<Route path="/children" component={fnComponent}/>
<Route path="/children" component={classComponent }/>
复制代码
注意官方有这句提示: if you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component. When using an inline function for inline rendering, use the render or the children prop .
翻译就是:行内函数(匿名函数)做为component属性传递(prop)时,会在每次渲染时建立一个react元素,这将从新挂载(mount)组件,而不是在既存的基础上更新。
这很好理解,匿名函数飘忽不定,每次render都意味着props的改变。若是实在用匿名函数,请选择children或render的方式
本文介绍了React-router的一些概念,谈了动态静态路由,react-router的体系,两种路由模式,导航方式、视图组件配置方式,内容有深有浅,纰漏在所不免,不足之处望读者朋友们留言或指正,谢谢!。
下一篇咱们会介绍React的打包相关