《All About React Router 4》 筆記

原文:

All About React Router 4

示例代碼

All About React Router 4 筆記

此文來自一篇英文博客,記錄學習時總結的一些知識點嫁怀,如有錯誤针余,請指正云矫,謝謝!

React Router 4 帶來新的API以及新的心智模型窒盐。

Inclusive Routing 引入路由

 const PrimaryLayout = () => (
  <div className="primary-layout">
    <header>
      Our React Router 4 App
      <Route path="/users" component={UsersMenu} />
    </header>
    <main>
      <Route path="/" exact component={HomePage} />
      <Route path="/users" component={UsersPage} />
    </main>
  </div>
)

UsersMenuUsersPage 可以通過同一個路由被渲染到當前頁面中啃奴,

exact 精確匹配路由 '/'

Switch 路由組

當你需要將路由匹配到一個路由組時潭陪,使用 Switch 可以匹配到唯一路由

const PrimaryLayout = () => (
  <div className="primary-layout">
    <PrimaryHeader />
    <main>
      <Switch>
        <Route path="/" exact component={HomePage} />
        <Route path="/users/add" component={UserAddPage} />
        <Route path="/users" component={UsersPage} />
        <Redirect to="/" />
      </Switch>
    </main>
  </div>
)

當使用 Switch 時,只有一個路由會被渲染。

我們仍然需要使用 exact 當設 HomePage 為首選被渲染的組件依溯。否則等瀏覽到 /users 或則會使 '/users/add' 時老厌,HomePage 組件仍然會被渲染,如果發(fā)生同時渲染黎炉,那么先渲染的組件排在最前面梅桩。

當路由匹配 /users/add 時,也會同時匹配到 /users 路由拜隧,為確保優(yōu)先渲染UserAddPage 可以將這個組件寫到 UsersPage 前面,如果相反趁仙,則調換順序洪添。
當然也可以將所有路由設置為 exact 精確匹配,這樣就不存在先后問題雀费。

Redirect 重定向

Switch 沒有匹配到任意一個路由的時候干奢,將會發(fā)生路由重定向。

"Index Routes" and "Not Found" (已移除)

在 V4 中不在使用 <IndexRoute>, 而是使用 <Route exact> 精確匹配路由盏袄。

如果沒有路由被匹配忿峻,可以使用 <Switch><Redirect> 去重定向到默認路由,或者重定向到 404頁面

Nested Layouts 嵌套布局

這里展示兩種不同的寫法辕羽,以及為什么第二種是更好的寫法

第一種采用 exact 精確匹配路由

const PrimaryLayout = props => {
  return (
    <div className="primary-layout">
      <PrimaryHeader />
      <main>
        <Switch>
          <Route path="/" exact component={HomePage} />
          <Route path="/users" exact component={BrowseUsersPage} />
          <Route path="/users/:userId" component={UserProfilePage} />
          <Route path="/products" exact component={BrowseProductsPage} />
          <Route path="/products/:productId" component={ProductProfilePage} />
          <Redirect to="/" />
        </Switch>
      </main>
    </div>
  )
}

這種寫法在技術上是可行的逛尚,但是問題在于,props.match 是通過 <Route> 組件傳遞的刁愿。組件 BrowseUsersPage 的子組件并不是通過 <Route> 嵌套路路由中绰寞,子組件是不能直接拿到 props.match的。

當然這里可以通過高階組件的方式將子組件包裝:withRouter()

第二種寫法在第一種寫法的基礎上做了修改铣口,通過路由嵌套的方式布局組件滤钱,并且不再需要使用 exact 精確匹配路由,也不必使用 withRouter() 加工組件脑题。

const PrimaryLayout = () => (
    <div className="primary-layout">
        <PrimaryHeader />
        <main>
            <Switch>
                <Route path="/" exact component={HomePage} />
                <Route path="/users" component={UserSubLayout} />
                <Route path="/products" component={ProductSubLayout} />
                <Redirect to="/" />
            </Switch>
        </main>
    </div>
);

const UserSubLayout = () => (
    <div className="user-sub-layout">
        <aside>
            <UserNav />
        </aside>
        <div className="primary-content">
            <Switch>
                <Route path="/users" exact component={BrowseUsersPage} />
                <Route path="/users/:userId" component={UserProfilePage} />
            </Switch>
        </div>
    </div>
);

const UserSubLayout = props => (
    <div className="user-sub-layout">
        <aside>
            <UserNav />
        </aside>
        <div className="primary-content">
            <Switch>
                <Route
                    path={props.match.path}
                    exact
                    component={BrowseUsersPage}
                />
                <Route
                    path={`${props.match.path}/:userId`}
                    component={UserProfilePage}
                />
            </Switch>
        </div>
    </div>
);

Match 匹配對象

Match 對象提供了一下幾種屬性

  • params - (object) Key/value pairs parsed from the URL corresponding to the dynamic segments of the path
  • isExact - (boolean) true if the entire URL was matched (no trailing characters)
  • path - (string) The path pattern used to match. Useful for building nested <Route>s
  • url - (string) The matched portion of the URL. Useful for building nested <Link>s

match.path vs match.url

當路由不攜帶參數(shù)是兩者的輸出是相同的字符串件缸,嘗試打印這兩者。

當路由匹配到例如 /users/5 時叔遂,match.url 將會輸出 "/users/5" ; 而 match.path 輸出 "/users/:userId".

Avoiding Match Collisions 避免匹配沖突

const UserSubLayout = ({ match }) => (
  <div className="user-sub-layout">
    <aside>
      <UserNav />
    </aside>
    <div className="primary-content">
      <Switch>
        <Route exact path={props.match.path} component={BrowseUsersPage} />
        <Route path={`${match.path}/add`} component={AddUserPage} />
        <Route path={`${match.path}/:userId/edit`} component={EditUserPage} />
        <Route path={`${match.path}/:userId`} component={UserProfilePage} />
      </Switch>
    </div>
  </div>
)

path-to-regexp 用于校驗路由參數(shù)

var re = pathToRegexp('/:foo(\\d+)')
// keys = [{ name: 'foo', ... }]

re.exec('/123')
//=> ['/123', '123']

re.exec('/abc')
//=> null

Authorized Route 路由認證他炊、權限管理

根據(jù)用戶登錄狀態(tài)管理其瀏覽路由的權限是應用中很常見的功能

with the help of v4 docs

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <BrowserRouter>
          <Switch>
            <Route path="/auth" component={UnauthorizedLayout} />
            <AuthorizedRoute path="/app" component={PrimaryLayout} />
          </Switch>
        </BrowserRouter>
      </Provider>
    )
  }
}

可以結合 react redux設計權限管理功能,<AuthorizedRoute> 組件先檢測當前的登錄狀態(tài)掏熬,
如果是正在登錄佑稠,則顯示 Loading...

如果已經(jīng)登錄則,則跳轉到到 <PrimaryLayout> 組件中

如果未登錄旗芬,則跳轉到登錄頁

class AuthorizedRoute extends React.Component {
  componentWillMount() {
    getLoggedUser()
  }

  render() {
    const { component: Component, pending, logged, ...rest } = this.props
    return (
      <Route {...rest} render={props => {
        if (pending) return <div>Loading...</div>
        return logged
          ? <Component {...this.props} />
          : <Redirect to="/auth/login" />
      }} />
    )
  }
}

const stateToProps = ({ loggedUserState }) => ({
  pending: loggedUserState.pending,
  logged: loggedUserState.logged
})

export default connect(stateToProps)(AuthorizedRoute)

Other mentions 其他

<Link> vs <NavLink>

這兩個功能一樣舌胶,都是路由跳轉,但是NavLink有一個屬性用來顯示跳轉選中的樣式疮丛,activeStyle屬性幔嫂,寫顯示高亮樣式的辆它,接收一個對象{}

在我們路由導航有一個to屬性

to屬性是我們路由的要跳轉的路徑:

import React from 'react'
import { NavLink } from 'react-router-dom'

const PrimaryHeader = () => (
  <header className="primary-header">
    <h1>Welcome to our app!</h1>
    <nav>
      <NavLink to="/app" exact activeClassName="active">Home</NavLink>
      <NavLink to="/app/users" activeClassName="active">Users</NavLink>
      <NavLink to="/app/products" activeClassName="active">Products</NavLink>
    </nav>
  </header>
)

export default PrimaryHeader

Dynamic Routes 動態(tài)路由

在 V4中最好的一部分改變是可以在所有地方包含 <Route> , 它只是一個 React 組件履恩。

路由將不再是神奇的東西锰茉,我們可以用在任何地方,試想一下切心,當滿足條件時飒筑,整個路由都可以被路由到。

在這些條件不滿足時绽昏,我們可以移除那些路由协屡,甚至,可以嵌套路由全谤。

React Router 4 變得更好用是因為這只是一個 Just Components?肤晓。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市认然,隨后出現(xiàn)的幾起案子补憾,更是在濱河造成了極大的恐慌,老刑警劉巖卷员,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盈匾,死亡現(xiàn)場離奇詭異,居然都是意外死亡子刮,警方通過查閱死者的電腦和手機威酒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挺峡,“玉大人葵孤,你說我怎么就攤上這事〕髟” “怎么了尤仍?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長狭姨。 經(jīng)常有香客問我宰啦,道長,這世上最難降的妖魔是什么饼拍? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任赡模,我火速辦了婚禮,結果婚禮上师抄,老公的妹妹穿的比我還像新娘漓柑。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布辆布。 她就那樣靜靜地躺著瞬矩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锋玲。 梳的紋絲不亂的頭發(fā)上景用,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音惭蹂,去河邊找鬼伞插。 笑死,一個胖子當著我的面吹牛盾碗,可吹牛的內容都是我干的蜂怎。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼置尔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了氢伟?” 一聲冷哼從身側響起榜轿,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎朵锣,沒想到半個月后谬盐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡诚些,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年飞傀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诬烹。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡砸烦,死狀恐怖,靈堂內的尸體忽然破棺而出绞吁,到底是詐尸還是另有隱情幢痘,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布家破,位于F島的核電站颜说,受9級特大地震影響,放射性物質發(fā)生泄漏汰聋。R本人自食惡果不足惜门粪,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烹困。 院中可真熱鬧未辆,春花似錦毡琉、人聲如沸昂秃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沙廉。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間辜御,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工屈张, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留擒权,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓阁谆,卻偏偏與公主長得像碳抄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子场绿,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內容

  • 第一次獨自承擔一個項目剖效,在進行技術選型時,由于看到了 React Router 4 的文檔十分完善焰盗,果斷地選擇了它...
    一個笑點低的妹紙閱讀 51,564評論 18 63
  • 你不知道的 React Router 4 幾個月前璧尸,React Router 4 發(fā)布,我能清晰地感覺到來自 Tw...
    楓上霧棋閱讀 1,977評論 2 11
  • React Router 4.0 (以下簡稱 RR4) 已經(jīng)正式發(fā)布熬拒,它遵循React的設計理念爷光,即萬物皆組件。所...
    梁相輝閱讀 97,334評論 24 195
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理澎粟,服務發(fā)現(xiàn)蛀序,斷路器,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • React-Router v4 1. 設計理念1.1. 動態(tài)路由1.2. 嵌套路由1.3. 響應式路由 2. 快速...
    wlszouc閱讀 8,543評論 0 14