React 初探(十一)

概述

之前已经将目录构建完成,这次主要将路由和页面结合起来,完成一些路由的切换和页面的跳转。我的项目地址

<BrowserRouter><HashRouter>

之前的文章中已经说明了 hashhistory 实现路由的方式,在 React-Router 中也有两种模式,即 <BrowserRouter><HashRouter>

<BrowserRouter>

<Router> 使用 HTML5 history API( pushStatereplaceStatepropsState 事件 )去保持你的 UI 和 URL 同步

属性:

  • basename: string -> 所有 location 的基本 URL。如果你的应用程序是从服务器上的子目录提供服务的,你需要将其设置为子目录。正确格式的 basename 应该有一个前导斜杠,并且没有尾随斜杠

  • getUserConfirmation: Function -> 用于确认导航的功能,默认为使用 window.confirm

  • forceRefresh: Boolean -> 如果为 true,路由将会在页面导航中使用整个刷新。你可能只希望在不支持 HTML5 history API 的浏览器中使用它

  • keyLength: Number -> location.keylength,默认是6

  • children: node -> render 单个子元素

<HashRouter>

<Router> 使用 URLhash 部分( window.location.hash ) 去保持你的 UI 和 URL 同步

注意:hash 历史不支持 location.key 或者 location.state。在以前的版本中,我们试图填充行为,但是有一些边缘情况不能解决。任何需要此行为的代码或插件都不能工作。由于此技术仅用于支持传统浏览器,因此建议使用 <BrowserRouter>

最佳实践

使用 <BrowserRouter>

Link + Route 实现路由跳转

可以通过 react-router<Link> + <Route> 实现路由跳转。

<BrowserRouter>
    <div className="router">
        <button className="link-button"><Link to="/">Home</Link></button>
        <button className="link-button"><Link to="/login">Login</Link></button>
        
        <Route path="/" exact component={Home} />
        <Route path="/login" exact component={Login} />
    </div>
</BrowserRouter>

<Link>

引入
import { Link } from 'react-router-dom'
属性
  • to : String -> 要链接的地址的字符串,通过连接的 locationpathnamesearchhash 创建

  • to: Object -> 可以具有以下任何属性的对象

    • pathname -> 一个字符串代表要去的路径( A string representing the path to link to. )
    • search -> 一个字符串代表查询参数( A string representation of query parameters. )
    • hash -> 一个 hash 放在 URL 中( A hash to put in the URL, e.g. #a-hash. )
    • state -> 状态已保留到该位置( State to persist to the location. )
  • replace: Boolean -> 当该值为 true ,点击这个 link 时在 history 栈中不会增加一个新的地址,而是会替代现在的地址

  • innerRef: Function -> 允许访问组件的基础引用

<Route>

<Route> 组件在 React-Router 中可能是最重要的去理解和学习良好使用的组件,它最基本的职责是在位置和路由路径匹配时呈现一些 UI。一旦应用程序 location 和 路由路径匹配,你的组件将会被渲染

引入
import { Route } from 'react-router-dom'
属性

Router render methods
这里有三种方式去 render 通过 <Route>

  • <Route component>
  • <Route render>
  • <Route children>

每一个都是有用的在不同的环境中。你应该使用其中一种在给定的 <Route>。查看他们的说明来理解为什么你有三个选项,大多数情况下你将会使用 component

  1. component
  • 渲染一个 React 组件只有当 location 匹配时,他将被 render 随着 route props

  • 当你使用 component 时,而不是下面的 renderchildrenrouter 使用 React.createElement 去创建一个新的 React element 从给定的组件中,这意味着如果你给组件提供一个 inline functionprops,每次 render 时你将会创建一个新的 component,这将导致现有的组件 unmount 和新的组件 mount 而不仅仅是更新现有组件。当使用 inline function 进行 inline render 时,使用下面的 renderchildren 属性

  1. render: Function
  • 这样可以方便的进行 inline renderwrapping 而无需上述不需要的重新安装

  • 你可以传递一个函数,当 location 匹配的时候该函数将会被调用,而不是使用组件属性为您创建一个新的 React elementrender 属性接收与 component 属性相同的所有 route props

注意: <Route component> 要优先于 <Route render> 所以不要在相同的 <Route> 中使用两者

3.children: Function

  • 有时你需要 render 路径是否与 location 相匹配,在这些情况下,你可以使用 children 属性。它的工作原理和 render 相同,除了无论是否匹配它都会被调用

  • children render 属性接收与 componentrender 方法相同的 route props,除了当路由和 URL 匹配失败时,matchnull。这允许你动态调整你的 UI 根据路由是否匹配。这里,如果路由匹配我们将会添加一个 active

注意:<Route component><Route render> 优先于 <Route children> 所以不要在相同的 <Route> 中使用两个或三个

Route props
所有的三个 render 方法将会具有三个相同的 route props

  • match
  • location
  • history
  1. path: string | string[]
    能够被解析的任何有效的 URL path 或者 path 数组

Routes without a path always match.( 没有路径的路由总是匹配的 )

  1. exact: Boolean
    如果为 true,则仅仅当 pathlocation.pathname 完全匹配时才匹配
path location.pathname exact matches?
/one /one/two true no
/one /one/two false yes
  1. strict: Boolean
    如果为 true,则带有尾随斜杠的路径将只与带有尾随斜杠的 location.pathname 匹配,当 location.pathname 中有其他 URL 部分时这是不起作用的
path location.pathname matches?
/one/ /one no
/one/ /one/ yes
/one/ /one/two yes

注意:strict 可以被用于强制 location.pathname 没有尾随斜杠,但是为了做这个 strictexact 必须都是 true

path location.pathname matches?
/one /one yes
/one /one/ no
/one /one/two no
  1. location: Object
    <Route> 元素尝试将其路径去和当前历史位置 location 匹配( 通常是当前浏览器 URL )。但是,也可以传递带有不同的 pathnamelocation 进行匹配。这是非常有用的假使当你需要将 <Route> 匹配到当前历史以外的 location
  • 如果一个 <Route> 元素被包裹在一个 <Switch> 中,并且与传递给 <Switch>location 匹配( 或当前历史位置 )。那么传递给 <Route>location 属性将被 <Switch> 使用的属性覆盖
  1. sensitive: Boolean
    如果为 true,路径匹配将区分大小写
path location.pathname sensitive matches?
/one /one true yes
/One /one true no
/One /one false yes

history + <Router> 实现路由跳转代码

然而上述的 <Link> + <Route> 并不能满足我们的需求,例如我们有时需要点击一个 button 之后先进行一些逻辑操作,之后再进行跳转,这时我们需要使用 history

historyhistory object 指的是 history package,它是 React Router 中的两个主要依赖项之一( 除了 React 本身 ),它提供了几种不同的实现方式,用于各种环境中来管理 JavaScript 中的会话 history

还使用以下术语:

  • browser history -> 一种特定于 DOM 的实现,在支持 HTML5 history API 的 Web 浏览器中非常有用
  • hash history -> 针对于传统 Web 浏览器的特定于 DOM 的实现
  • memory history -> 内存中的历史实现,在测试和非 DOM 环境( 如 React native )中非常有用

属性 | 方法

  • length: Number -> 历史记录堆栈中的条目数
  • action: String -> 当前的操作( pushreplacepop )
  • location: Object -> 当前的 location,可能含有下列属性:
    • pathname: String -> URL 的路径
    • search: String -> URLquery 字符串
    • hash: String -> URLhash 片段
    • state: Object -> 提供给特定未知的状态,例如,将此位置推送到堆栈时的推送( 路径、状态 )。仅在浏览器和内存历史记录中可用
  • push( path [, state] ): Function -> 将新条目推送到历史堆栈中
  • replace( path [, state] ): Function -> 替换历史堆栈上的当前条目
  • go( n ): Function -> 将历史堆栈中的指针移动 n 个条目
  • goBack(): Function -> 等同于 go( -1 )
  • goForward(): Function -> 等同于 go( 1 )
  • block( prompt ): Function -> 阻止导航

注意:history 对象是可变的。因此,建议从 <route>render props 访问 location,而不是从 history.location ,这可以确保您对 React 的假设在生命周期函数中是正确的。

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

推荐阅读更多精彩内容