React-8:路由React Router

路由

        当应用变得复杂的时候,就需要分块的进行处理和展示,传统模式下,我们是把整个应用分成了多个页面,然后通过 URL 进行连接。

        但是这种方式也有一些问题,每次切换页面都需要重新发送所有请求和渲染整个页面,不止性能上会有影响,同时也会导致整个

         JavaScript 重新执行,丢失状态。


SPA

        Single Page Application : 单页面应用

        整个应用只加载一个页面(入口页面),后续在与用户的交互过程中,通过 DOM 操作在这个单页上动态生成结构和内容

        优点:

                - 有更好的用户体验(减少请求和渲染和页面跳转产生的等待与空白),页面切换快

                - 重前端,数据和页面内容由异步请求(AJAX)+ DOM 操作来完成,前端处理更多的业务逻辑

        缺点:

                - 首屏处理慢

                - 不利于 SEO


SPA 的页面切换机制

        虽然 SPA 的内容都是在一个页面通过 JavaScript 动态处理的,但是还是需要根据需求在不同的情况下分内容展示,如果仅仅只是

        依靠 JavaScript 内部机制去判断,逻辑会变得过于复杂,通过把 JavaScript 与 URL 进行结合的方式: JavaScript 根据 URL  的变化,

        来处理不同的逻辑,交互过程中只需要改变 URL 即可。这样把不同 URL 与 JavaScript 对应的逻辑进行关联的方式就是路由,其本质

        上与后端路由的思想是一样的。


后端路由与前端路由

        后端路由与前端路由在本质上是类似的,都是把不同的 URL 与某个操作进行关联绑定,得到不一样的结果


后端路由

        通过 HTTP 把请求发送到后端服务器,后端服务器接收到请求以后根据不同的请求 URL 来执行不同的操作,返回处理好的数据

        (JSON、HTML、JS 代码、CSS、图像……)

                - 需要发送 HTTP 请求

                - 业务逻辑由后端处理,返回处理后的结果给前端(浏览器)


前端路由

        前端路由只是改变了 URL 或 URL 中的某一部分,但一定不会直接发送请求,可以认为仅仅只是改变了浏览器地址栏上的 URL 

        而已,JavaScript 通过各种手段处理这种 URL 的变化,然后通过 DOM 操作动态的改变当前页面的结构

                - URL 的变化不会直接发送 HTTP 请求

                - 业务逻辑由前端 JavaScript 来完成

        目前前端路由主要的模式:

                - 基于 URL Hash 的路由

                - 基于 HTML5 History API 的路由


URL Hash

        通过通过修改 URL 的 Hash 值来改变 URL,Hash 的变化是不会发送请求的,同时 JavaScript 通过监听 hashchange 事件来动态

        处理逻辑和页面渲染

            优点

                    兼容性好

            缺点

                    URL 不美观,SEO 不友好


HTML5 History API

        封装一个函数,该函数通过 HTML5 History 提供的 API 来动态改变 URL ,这种方式也不会发送请求,然后同时根据要改变的

        目标 URL 来处理逻辑和页面渲染

                URL Hash 模式类似 Vue 中的数据拦截机制

                HTML5 History API 模式类似 React.js 中的 setState



React.js 中的路由

        React.js 路由的基本思想就是,把不同的 URL 与 指定的某些 React.js 组件进行关联,不同的 URL 渲染显示不同的组件,其它

        框架(如:vue、angular) 都是一样的思想


React Router

        理解了路由基本机制以后,也不需要重复造轮子,我们可以直接使用 React Router 库

                https://reacttraining.com/react-router/

        React Router 提供了多种不同环境下的路由库

                - web

                - native


基于 Web 的 React Router

        基于 web 的 React Router 为:react-router-dom

安装

        npm i -S react-router-dom

概览

        react-router-dom 的核心是组件,它提供了一系列的组件,如:

                - Router 组件

                - BrowserRouter 组件

                - HashRouter 组件

                - Route 组件

                - Link 组件

                - NavLink 组件

                - Switch 组件

                - Redirect 组件

        以及其它一些 API,来完成路由的功能


Router 组件

        如果我们希望页面中某个部分的内容需要根据 URL 来动态显示,需要用到 Router 组件 ,该组件是一个容器组件,只需要用

        它包裹 URL 对应的根组件即可

       react-router-dom 为我们提供了几个基于不同模式的 router 子组件

                - BrowserRouter 组件

                - HashRouter 组件

                - MemoryRouter 组件

                - NativeRouter 组件

                - StaticRouter 组件


BrowserRouter 组件

        基于 HTML5 History API 的路由组件

HashRouter 组件

        基于 URL Hash 的路由组件

Route 组件

        注意这个组件是没有字母 r 的,通过该组件来设置应用单个路由信息,Route 组件所在的区域就是就是当 URL 与当前 Route

         设置的 path 属性匹配的时候,后面 component 将要显示的区域

<Route path='/' component={Home} />

        当 URL 为:'/' 的时候,组件 Home 将显示在这里


exact

        exact 属性表示路由使用 精确匹配模式,非 exact 模式下 '/' 匹配所有以 '/' 开头的路由


Link 组件

        Link 组件用来处理 a 链接 类似的功能(它会在页面中生成一个 a 标签),但设置这里需要注意的,react-router-dom 拦截了实际

         a标签的默认动作,然后根据所有使用的路由模式(Hash 或者 HTML5)来进行处理,改变了 URL,但不会发生请求,同时根据 

        Route 中的设置把对应的组件显示在指定的位置

to 属性

        to 属性类似 a 标签中的 href


状态提升

        前面讲组件中提到过组件状态提升,如果多个组件需要共享一个状态,那么就讲状态提升到使用该状态的共同父级组件上

传递 props

<Route exact path='/' component={Home}

        如果 Route 使用的是 component 来指定组件,那么不能使用 props

Route : render

<Route exact path='/' render={() => <Home items={this.state.items} />} />

        通过 render 属性来指定渲染函数,render 属性值是一个函数,当路由匹配的时候指定该函数进行渲染


params

        在路由中,params 指的是 path 部分可变的部分,在这里我们需要定义一个新的路由用来展示商品的详情,我们希望通过 /item/1 、

        /item/2、/item/…… 来访问对应 id 的商品,那么后面的数字部分就是可变的 - params,我们也称这样的路由为:动态路由

动态路由

        为了能给处理上面的动态路由地址的访问,我们需要为 Route 组件配置特殊的 path

<Route path='/item/:id' component={Item} />

path-to-regexp

        path-to-regexp 是一个专门用来处理 URL 的库,它用来了一种类似正则的字符串表示法

        `:` 表示后面的部分为可变,`:` 后面的单词为匹配后的内容存储的名称,如:/item/1 ,就是 `id=1`

        默认情况下,它为我们提供了几个常用的字符表示:*、?、+

        但是我们可以通过 `()` 来使用正则

<Route path='/item/:id(\d+)' component={Item} />

        上面表示 /item/ 后面只能是数字

Route : props

        当动态路由匹配以后,我们可以通过对应组件的 props 属性来访问当前路由匹配信息

路由组件

        如果一个组件是通过路由直接访问的,我们称为:路由组件 - 视图组件,其它的类型,根据具体功能可以称为:业务组件,

        UI 组件,容器组件,……

        如果一个组件是路由组件,那么组件的 props 属性就会自动添加几个与路由有关的几个属性

match : params

this.props.match.params.id

        如果一个组件既要接收手动传入的 props,又想接收路由信息

<Route path='/item/:id(\d+)' render={props => <Item {...props} items={this.state.items} />} />

案例:

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

推荐阅读更多精彩内容

  • 前言 react-router针对不同的使用场景衍生了不同的路由包,RN项目用react-router-nativ...
    大柚子08阅读 36,455评论 5 39
  • React Router教程 React项目的可用的路由库是React-Router,当然这也是官方支持的。它也分...
    CLYDE_6715阅读 266评论 0 0
  • React Router教程 React项目的可用的路由库是React-Router,当然这也是官方支持的。它也分...
    惊蛰_5269阅读 300评论 0 0
  • React Router教程 React项目的可用的路由库是React-Router,当然这也是官方支持的。它也分...
    __db84阅读 728评论 0 0
  • 现在是德国时间19.42。 其实在打开这个网页之前我不知道要做什么。 看了会儿两个姐姐的微博,觉得自己还可以做更多...
    新竹野猴子阅读 87评论 0 0