React Router 4.0 (以下简称 RR4) 已经正式发布,它遵循react的设计理念,即万物皆组件。所以 RR4 只是一堆 提供了导航功能的组件(还有若干对象和方法),具有声明式(引入即用),可组合性的特点。http://www.jianshu.com/p/e3adc9b5f75c
RR4 本次采用单代码仓库模型架构(monorepo),这意味者这个仓库里面有若干相互独立的包,分别是:
react-router
React Router 核心react-router-dom
用于 DOM 绑定的 React Routerreact-router-native
用于 React Native 的 React Routerreact-router-redux
React Router 和 Redux 的集成react-router-config
静态路由配置的小助手
最新版的React Router(v4)有以下几个发行包,可能从之前版本用过来的同学会有一些疑惑,我到底该用哪一个啊?
react-router
React Router 的核心公用组件和方法。具体如下: MemoryRouter、
Prompt、
Redirect、
Route、
Router
StaticRouter、
Switch、
matchPath、
withRouter
react-router-dom
React Router for WEB,一般我们前端就用这个包来进行WEB开发了,提供包括上述react-router相关的组件和方法以外还有如下接口:BrowserRouter、
HashRouter、
Link
、NavLink
react-router-native
React Router 给react-native提供额外路由相关支持,包括:NativeRouter、
Link、
DeepLinking
AndroidBackButton
,感兴趣的同学可以访问这里 https://reacttraining.com/react-router/native/guides/quick-start 研究下。
react-router-redux
最新的版本还在测试版本中,如果你项目里面同时用到了react-router 和 redux,然后想把各种路由状态存储在app的状态里面,就可以用这个库了。这个库也辅助的,操作路由切换,如: dispatch( push('/xx') )
react-router-config
该包主要提供如下接口:matchRoutes
、renderRoutes
,官方说明 https://github.com/ReactTraining/react-router/tree/master/packages/react-router-config
从React Router V4 开始,APP路由配置就不需要集中到一个地方了。但有些情况下我们还是需要集中配置一些路由,这个包就是来辅助做这些的,它尝试建立一种共享的模式,让上层应用基于它来构建这些路由配置。
综上,再也不用纠结该用哪个包了,每个包都有些什么了,如果不是做native相关的就用 react-router-dom
,如果你是做react-native相关的应用就毫不犹豫的选择用 react-router-native
来构建你的应用路由咯。
原文来自:https://fiture.me/share/javascript/1254.html
引用react-router 还是 react-router-dom?
然后在React的使用中,我们一般要引入两个包,react和react-dom;那么react-router 和react-router-dom是不是两个都要引用呢?
不是,两者引用一个就行了,不同之处就是后者比前者多出了<Link><BrowserRouter>这样的DOM类组件。
因此我们只需要引用reac-router-dom这个包就行了,当然,如果要搭配redux,你还需要使用react-router-redux
reac-router-dom组件说明
<BrowserRouter>
一个使用了 HTML5 history API 的高阶路由组件,保证你的 UI 界面和 URL 保持同步。此组件拥有以下属性:
basename: string
作用:为所有位置添加一个基准URL
使用场景:假如你需要把页面部署到服务器的二级目录,你可以使用 basename
设置到此目录。
<BrowserRouter basename="/minooo" /> <Link to="/react" /> // 最终渲染为 <a href="/minooo/react">
BrowserRouter详细说明:http://blog.csdn.net/sinat_17775997/article/details/69218382
其中,HashRouter和BrowserRouter的区别使用
从上面动图可以看出:当我们刷新浏览器的时候 就出问题了。
现在我们把BrowserRouter改成HashRouter,
主要引入的包不同
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; #改为 import { HashRouter as Router, Route, Link } from 'react-router-dom'
就是把BrowserRouter
改成HashRouter
即可。
现在刷新浏览器就不会出错了。
import React, { Component } from 'react'; import { HashRouter, Switch, Route, Redirect } from 'react-router-dom'; import asyncComponent from '@/utils/asyncComponent'; import home from "@/pages/home/home"; const record = asyncComponent(() => import("@/pages/record/record")); const helpcenter = asyncComponent(() => import("@/pages/helpcenter/helpcenter")); const production = asyncComponent(() => import("@/pages/production/production")); const balance = asyncComponent(() => import("@/pages/balance/balance")); // react-router4 不再推荐将所有路由规则放在同一个地方集中式路由,子路由应该由父组件动态配置,组件在哪里匹配就在哪里渲染,更加灵活 export default class RouteConfig extends Component{ render(){ return( <HashRouter> <Switch> <Route path="/" exact component={home} /> <Route path="/record" component={record} /> <Route path="/helpcenter" component={helpcenter} /> <Route path="/production" component={production} /> <Route path="/balance" component={balance} /> <Redirect to="/" /> </Switch> </HashRouter> ) } }
原文来自:http://blog.csdn.net/github_26672553/article/details/76906488
<Route>
<Route> 也许是 RR4 中最重要的组件了,重要到你必须理解它,学会它,用好它。它最基本的职责就是当页面的访问地址与 Route 上的 path 匹配时,就渲染出对应的 UI 界面。
<Route> 自带三个 render method 和三个 props 。
render methods 分别是:
<Route component>
<Route render>
<Route children>
每种 render method 都有不同的应用场景,同一个<Route>
应该只使用一种 render method ,大部分情况下你将使用component
。
props 分别是:
match
location
history
所有的 render method 无一例外都将被传入这些 props。
component
只有当访问地址和路由匹配时,一个 React component 才会被渲染,此时此组件接受 route props (match, location, history)。
当使用 component
时,router 将使用 React.createElement
根据给定的 component 创建一个新的 React 元素。这意味着如果你使用内联函数(inline function)传值给 component
将会产生不必要的重复装载。对于内联渲染(inline rendering), 建议使用 render
prop。
<Route path="/user/:username" component={User} /> const User = ({ match }) => { return <h1>Hello {match.params.username}!</h1> }
render: func
此方法适用于内联渲染,而且不会产生上文说的重复装载问题。
// 内联渲染 <Route path="/home" render={() => <h1>Home</h1} /> // 包装 组合 const FadingRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => ( <FadeIn> <Component {...props} /> </FaseIn> )} /> ) <FadingRoute path="/cool" component={Something} />
<Route path="/detail/:kerwinId" render={props=> <Detail {...props} kerwin="ok" /> }>
</Route>
<Route path='/detail/:id' render={props => ( <Detail props={props}/> )}/> <Route path='/search/:category/:keyword?' render={props => ( <Search props={props}/> )}/> <Route path='/css' render={props => ( <CSS props={props}/> )}/> <Route path='/js' render={props => ( <JS props={props}/> )}/> <Route render={props => ( <NotFound props={props}/> )}/>
path: string
任何可以被 path-to-regexp解析的有效 URL 路径
<Route path="/users/:id" component={User} />
Route详细说明:http://blog.csdn.net/sinat_17775997/article/details/69218382
<Link>
为你的应用提供声明式,无障碍导航。
to: string
作用:跳转到指定路径
使用场景:如果只是单纯的跳转就直接用字符串形式的路径。
<Link to="/courses" />
to: object
作用:携带参数跳转到指定路径
作用场景:比如你点击的这个链接将要跳转的页面需要展示此链接对应的内容,又比如这是个支付跳转,需要把商品的价格等信息传递过去。
<Link to={{ pathname: '/course', search: '?sort=name', state: { price: 18 } }} />
replace: bool
为 true 时,点击链接后将使用新地址替换掉上一次访问的地址,什么意思呢,比如:你依次访问 '/one' '/two' '/three' ’/four' 这四个地址,如果回退,将依次回退至 '/three' '/two' '/one' ,这符合我们的预期,假如我们把链接 '/three' 中的 replace 设为 true 时。依次点击 one two three four 然后再回退会发生什么呢?会依次退至 '/three' '/one'! 为此我做了个在线 demo,大家可以调试体会一下 !
Link详细说明:http://blog.csdn.net/sinat_17775997/article/details/69218382
<NavLink>
这是 <Link> 的特殊版,顾名思义这就是为页面导航准备的。因为导航需要有 “激活状态”。
activeClassName: string
导航选中激活时候应用的样式名,默认样式名为 active
<NavLink to="/about" activeClassName="selected" >MyBlog</NavLink>
activeStyle: object
如果不想使用样式名就直接写style
<NavLink to="/about" activeStyle={{ color: 'green', fontWeight: 'bold' }} >MyBlog</NavLink>
exact: bool
若为 true,只有当访问地址严格匹配时激活样式才会应用
strict: bool
若为 true,只有当访问地址后缀斜杠严格匹配(有或无)时激活样式才会应用
isActive: func
决定导航是否激活,或者在导航激活时候做点别的事情。不管怎样,它不能决定对应页面是否可以渲染。
NavLink详细说明:http://blog.csdn.net/sinat_17775997/article/details/69218382
例子:
<NavLink to={`${this.props.match.path}/passed`} className="nav-link">已通过</NavLink> <NavLink to={`${this.props.match.path}/audited`} className="nav-link">待审核</NavLink>
<NavLink to={`${this.props.match.path}/failed`} className="nav-link">未通过</NavLink>
import React, { Component } from 'react'; import { NavLink, Switch, Route, Redirect } from 'react-router-dom'; import PublicHeader from '@/components/header/header'; import RecordList from './components/recordList'; import './record.css'; class Record extends Component { state = { flagBarPos: '17%', } /** * 设置头部底部标签位置 * @param {string} type 数据类型 */ setFlagBarPos = type => { let flagBarPos; switch(type){ case 'passed': flagBarPos = '17%'; break; case 'audited': flagBarPos = '50%'; break; case 'failed': flagBarPos = '83%'; break; default: flagBarPos = '17%'; } this.setState({flagBarPos}) } componentWillMount(){ // 初始化设置头部底部标签位置 let type = this.props.location.pathname.split('/')[2]; this.setFlagBarPos(type); } render() { return ( <main className="common-con-top"> <PublicHeader title='记录' /> <section className="record-nav-con"> <nav className="record-nav"> <NavLink to={`${this.props.match.path}/passed`} className="nav-link">已通过</NavLink> <NavLink to={`${this.props.match.path}/audited`} className="nav-link">待审核</NavLink> <NavLink to={`${this.props.match.path}/failed`} className="nav-link">未通过</NavLink> </nav> <i className="nav-flag-bar" style={{left: this.state.flagBarPos}}></i> </section> {/* 子路由在父级配置,react-router4新特性,更加灵活 */} <Switch> <Route path={`${this.props.match.path}/:type`} component={RecordList} /> <Redirect from={`${this.props.match.path}`} to={`${this.props.match.path}/passed`} exact component={RecordList} /> </Switch> </main> ); } } export default Record;
本地效果为:D:\www\svn\project\react_redux\src\pages\record
<Switch>
只渲染出第一个与当前访问地址匹配的 <Route>
或 <Redirect>
。
思考如下代码,如果你访问 /about
,那么组件 About User Nomatch 都将被渲染出来,因为他们对应的路由与访问的地址 /about
匹配。这显然不是我们想要的,我们只想渲染出第一个匹配的路由就可以了,于是 <Switch>
应运而生!
<Route path="/about" component={About}/> <Route path="/:user" component={User}/> <Route component={NoMatch}/>
children: node<Switch>
下的子节点只能是 <Route>
或 <Redirect>
元素。只有与当前访问地址匹配的第一个子节点才会被渲染。<Route>
元素用它们的 path
属性匹配,<Redirect>
元素使用它们的 from
属性匹配。如果没有对应的 path
或 from
,那么它们将匹配任何当前访问地址。
Switch详细说明:http://blog.csdn.net/sinat_17775997/article/details/69218382
<Redirect>
<Redirect>
渲染时将导航到一个新地址,这个新地址覆盖在访问历史信息里面的本该访问的那个地址。
to: string
重定向的 URL 字符串
to: object
重定向的 location 对象
push: bool
若为真,重定向操作将会把新地址加入到访问历史记录里面,并且无法回退到前面的页面。
from: string
需要匹配的将要被重定向路径。
Redirect详细说明:http://blog.csdn.net/sinat_17775997/article/details/69218382
Prompt
对象和方法 history、location、match
比如从首页进入到详情页得时候配合
<Route path="/detail/:kerwinId" render={props=> <Detail {...props} kerwin="OK"/> }> </Route>
render(){ console.log(this.props) }
详情页console.log得值
history:Object { action: "PUSH" //string 路由跳转到当前页面执行的动作,分为 PUSH, REPLACE, POP length: 15 //number 浏览历史堆栈中的条目数 location: Object { hash: "" //string URL的 hash 片段 key: "um0f9t" pathname: "/detail/3794" //string URL路径 search: "" // string URL中的查询字符串 state: undefined //string 例如执行 push(path, state) 操作时,location 的 state 将被提供到堆栈信息里,state 只有在 browser 和 memory history 有效。 } go:funciton go(n) //将 history 堆栈中的指针向前移动 n goBack:function goBack() //等同于 go(-1) goForward:function goForward() //等同于 go(1) block:function block() //阻止跳转 push:function push(path, state) //在历史堆栈信息里加入一个新条目。 replace:function replace(path, state) //在历史堆栈信息里替换掉当前的条目 } kerwin: "ok" location: Object { hash: "" key: "um0f9t" pathname: "/detail/3794" search: "" state: undefined } match: Object { isExact: true // bool 为 true 时,整个 URL 都需要匹配 params: Object //object 路径参数,通过解析 URL 中的动态部分获得键值对 { kerwinId: "3794" } path: "/detail/:kerwinId" //string 用来匹配的路径模式,用于创建嵌套的 <Route> url: "/detail/3794" //string URL 匹配的部分,用于嵌套的 <Link> } staticContext: undefined
详细说明在:http://blog.csdn.net/sinat_17775997/article/details/69218382
react-router4router搭配例子
import React from "react"; import ReactDOM from "react-dom"; import { BrowserRouter as Router, Route, Link, Redirect, Switch } from 'react-router-dom' import App from "./components/App/index"; import Home from "./components/Home/index"; import Cinema from "./components/Cinema/index"; import Me from "./components/Me/index"; import Card from "./components/Card/index"; import Film from "./components/Film/index"; import NowPlaying from "./components/NowPlaying/index"; import ComingSoon from "./components/ComingSoon/index"; import Detail from "./components/Detail/index"; const router = ( <Router> <App> <Switch> {/*Renders the first child <Route> or <Redirect> that matches the location.*/} <Route path="/home" component={Home} /> <Route path="/film" render={()=> <Film> <Switch>{/*Renders the first child <Route> or <Redirect> that matches the location.*/} <Route path="/film/now-playing" component={NowPlaying}/> <Route path="/film/coming-soon" component={ComingSoon}/> <Redirect from="/film" to="/film/now-playing"/> {/*重定向*/} </Switch> </Film> }> </Route> <Route path="/cinema" component={Cinema}> </Route> <Route path="/me" component={Me}> </Route> <Route path="/card" component={Card} > </Route> <Route path="/detail/:kerwinId" render={props=> <Detail {...props} kerwin="OK"/> }> </Route> <Redirect from="/" to="/home"/> {/*重定向*/} </Switch> </App> </Router> ) //export default router; ReactDOM.render(router,document.getElementById("box"));
本地效果查看为:http://localhost:8088/home
关于react route自从升级到4.1.1版本之后,直接
<Router history={browserHistory}></Router>
请确保安装一下模块
"react": "^15.6.1", "react-dom": "^15.6.1", "react-router": "^4.1.1", "react-router-dom": "^4.1.1"