React-Router4.0小结

react-router 还是 react-router-dom?

在 React 的使用中,我们一般要引入两个包,react 和 react-dom,那么 react-router 和react-router-dom 是不是两个都要引用呢?
非也,坑就在这里。他们两个只要引用一个就行了,不同之处就是后者比前者多出了 <Link> <BrowserRouter> 这样的 DOM 类组件。因此我们只需引用 react-router-dom 这个包就行了

react-router: 实现了路由的核心功能
react-router-dom: 基于react-router,加入了在浏览器运行环境下的一些功能,例如:Link组件,会渲染一个a标签,Link组件源码a标签行; BrowserRouterHashRouter组件,前者使用pushStatepopState事件构建路由,后者使用window.location.hashhashchange事件构建路由。

react-router-dom依赖react-router,所以我们使用npm安装依赖的时候,只需要安装相应环境下的库即可,不用再显式安装react-router。基于浏览器环境的开发,只需要安装react-router-dom;npm会自动解析react-router-dom包中package.json的依赖并安装。
react-router-dom中package.json依赖:

"dependencies": {
    "history": "^4.7.2",
    "invariant": "^2.2.2",
    "loose-envify": "^1.3.1",
    "prop-types": "^15.5.4",
    "react-router": "^4.2.0",
    "warning": "^3.0.0"
  }

React-Router4.0不允许出现嵌套的子路由

例如:

<Router>
    <Route path="/" component={App}>
      <Route path="about" component={About} />
      <Route path="inbox" component={Inbox} />
    </Route>
  </Router>

React-Router4.0主张将路由拆分出来,不直接使用嵌套路由
源文件改为

<BrowserRouter>
    <Route path="/" component={App}></Route>
</BrowserRouter>

然后在APP组件里面再次写入

<Switch>
  <Route path="about" component={About} />
  <Route path="inbox" component={Inbox} />
<Switch>

只渲染第一个匹配的组件<Switch>: 一个路由可能同时匹配多个路径,在<Switch>中,只渲染匹配的第一个,其他的放弃。之前这是Router的默认行为,4.0中不默认了

在react-router 2.0中可选参数是这样写的

<Route path='/index(/:hello)' />

而在react-4.0中你会惊喜的发现这种写法没用了

要写成这样

<Route path='/index/:hello?' />

后边的问号表示这个参数是可选的

Router变化

react-router将history分为三类。

  • hashHistory 老版本浏览器的history
  • browserHistory h5的history
  • createMemoryHistory node环境下的history,存储在memory中

4.0之前版本的react-router针对三者分别实现了createHashHistory、createBrowserHistory和create MemoryHistory三个方法来创建三种情况下的history,这里就不讨论他们不同的处理方式了,好奇的可以去了解一下~
到了4.0版本,在react-router-dom中直接将这三种history作了内置,于是我们看到了BrowserRouter、HashRouter、MemoryRouter这三种Router,当然,你依然可以使用React-router中的Router,然后自己通过createHistory来创建history来传入。

Route标签

它最基本的职责就是当页面的访问地址与 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

location对象包括:

  • pathname 同window.location.pathname
  • search 同window.location.search
  • state 一个捆绑在这个地址上的object对象
  • action PUSH, REPLACE, 或者 POP中的一个
  • key 唯一ID

发现 location.query属性没有了,现在通过 'query-string' 模块进行转换获取
import queryString from 'query-string'
let query=this.query=queryString.parse(location.search);
match 对象包含了 <Route path> 如何与 URL 匹配的信息,具有以下属性:

match对象包括:

  • params: object 路径参数,通过解析 URL 中的动态部分获得键值对
  • isExact: bool 为 true 时,整个 URL 都需要匹配
  • path: string 用来匹配的路径模式,用于创建嵌套的 <Route>
  • url: string URL 匹配的部分,用于嵌套的 <Link>

存: this.props.history.push({pathname:"/web/updateStaff/" + text.userId});
读:this.props.match.params.userId

想了解更详细的参数传递,可以参考 https://www.jianshu.com/p/ad8cc02b9e6c

BrowserRouter和HashRouter区别

hashHistory使用 URL 中的 hash(#)部分去创建路由,举例来说,用户访问http://www.example.com/,实际会看到的是http://www.example.com/#/

当页面刷新的时候,对于BrowserHistory, 浏览器会向后台发送整个URL的请求, 而对于HashHistory, 它只会请求后台的根目录。

browserHistory 是使用 React-Router 的应用推荐的 history方案。它使用浏览器中的 History API 用于处理 URL,创建一个像example.com/list/123这样真实的 URL 。
在browserHistory 模式下,URL 是指向真实 URL 的资源路径,当通过真实 URL 访问网站的时候,由于路径是指向服务器的真实路径,但该路径下并没有相关资源,所以用户访问的资源不存在。
当本地使用browserHistory , 因为webpack.config.js中使用 webpack-dev-server 已经做了配置。所以不会出现刷新页面404.

webpackConfig.devServer = {
        contentBase: path.resolve(__dirname, 'build'),
        compress: true, //gzip压缩
        historyApiFallback: true,
    };

但是要想在发版后正常使用,服务器需要进行相关路由配置,参考 (这里):

问题解决

1.使用render加载组件后,组件加载不出来

https://blog.csdn.net/aqtata/article/details/76169974

2.为什么用 this.props.history.push({......})不起作用

用此方法不起作用说明,你直接引用的Router路由,在ReactRouter4.x里Router里面并没有内置history对象,React Router 是建立在 history 之上的。 简而言之,一个 history 知道如何去监听浏览器地址栏的变化, 并解析这个 URL 转化为 location 对象, 然后 router 使用它匹配到路由,最后正确地渲染对应的组件。所以你只能通过createHistory创建的自定义的history对象,并将其传入Router传入来实现路由动态跳转

// HTML5 history, 推荐
import createHistory from 'history/lib/createBrowserHistory'

// Hash history
import createHistory from 'history/lib/createHashHistory'

// 内存 history (如:node环境)
import createHistory from 'history/lib/createMemoryHistory'
const history = createHistory()
......
<Router history={history }></Router>

history 一个管理js应用session会话历史的js库。它将不同环境(浏览器,node...)的变量统一成了一个简易的API来管理历史堆栈、导航、确认跳转、以及sessions间的持续状态。

3.为什么使用IndexRoute会报错

因为react-router4*已经抛弃了IndexRoute
以前

<BrowserRouter>
   <Route path="/" component={Frame}>
        <IndexRoute component={Home} />
        <Route path="/detail" component={Detail}></Route>      
    </Route>
 </BrowserRouter>

现在的默认路由为

<BrowserRouter>
    <Frame>             
       <Route path="/" exact component={Home}/>
       <Route path="/detail" component={Detail}></Route>         
     </Frame>
  </BrowserRouter>     
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,176评论 5 469
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,190评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,232评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,953评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,879评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,177评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,626评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,295评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,436评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,365评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,414评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,096评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,685评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,771评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,987评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,438评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,032评论 2 341

推荐阅读更多精彩内容

  • React Router 4.0 (以下简称 RR4) 已经正式发布,它遵循React的设计理念,即万物皆组件。所...
    梁相辉阅读 97,293评论 24 195
  • React-Router v4 1. 设计理念1.1. 动态路由1.2. 嵌套路由1.3. 响应式路由 2. 快速...
    wlszouc阅读 8,534评论 0 14
  • 一、基本用法 React Router 安装命令如下。 $ npm install -S react-router...
    sunnyghx阅读 4,490评论 0 6
  • 世界上最痛苦的事儿不是人活着钱没了 而是被催婚 寸姐也被催过婚 坦白讲这种痛苦旁人真的很难理解 当老一辈人用老思想...
    半点分寸阅读 657评论 0 0
  • 刹那 缘起 其实这个问题,本身就是回答! 闲赋在家一段时间,看了一堆书后,正准备写点东西时,通过简书的小丸子,知道...
    木子胧阅读 266评论 9 5