React Router 4

博主翻譯原教程目的(加了一些博主自己解讀),一是博主自己進(jìn)一步了解React Router 4,二是官網(wǎng)的教程確實(shí)還需加強(qiáng)引導(dǎo)性和增加案例多樣性。從React Router 4 的心智模型。看后面對(duì)這個(gè)詞的解釋,就明白了有些伙伴們對(duì)4的質(zhì)疑。

目的

此指南的目的為了說明使用 React Router 4 時(shí)的心智模型。我們稱之為的”動(dòng)態(tài)路由“,這與你熟悉的”靜態(tài)路由“有很大的不同。

注釋:心智模型是經(jīng)由經(jīng)驗(yàn)及學(xué)習(xí),腦海中對(duì)某些事物發(fā)展的過程,所寫下的劇本,是個(gè)體為了要了解和解釋他們的經(jīng)驗(yàn),所建構(gòu)的知識(shí)結(jié)構(gòu),該模型受限于個(gè)體關(guān)于他們經(jīng)驗(yàn)的內(nèi)隱理論,這可能有很多或很少的正確性。

靜態(tài)路由

如果你使用 Rails, Express, Ember, Angular 等。你已經(jīng)使用了靜態(tài)路由。在這些框架中,在任何渲染發(fā)生之前,將申明路由作為應(yīng)用程序初始化一部分。
React Router 4 之前的版本也是靜態(tài)的(主要是)。讓我們看看在 Express 里如何配置路由:

const express = require('express');
const app = express();

app.get('/', handleIndex)
app.get('/invoices', handleInvoices)
app.get('/invoices/:id', handleInvoice)
app.get('/invoices/:id/edit', handleInvoiceEdit)

app.listen()

注意:在應(yīng)用程序監(jiān)聽之前如何讓路由被申明。這和我們使用的客戶端路由是相似的。在 Angular 中,首先申明路由并且在渲染之間把他們導(dǎo)入到頂級(jí)的 AppMoudule :

const appRoutes: Routes = [
  { path: 'crisis-center',
    component: CrisisListComponent
  },
  { path: 'hero/:id',
    component: HeroDetailComponent
  },
  { path: 'heroes',
    component: HeroListComponent,
    data: { title: 'Heroes List' }
  },
  { path: '',
    redirectTo: '/heroes',
    pathMatch: 'full'
  },
  { path: '**',
    component: PageNotFoundComponent
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes)
  ]
})

export class AppModule { }

Ember有一個(gè)常規(guī)的 routes.js 文件,它可以構(gòu)建讀取并導(dǎo)入到應(yīng)用程序里。同樣,在應(yīng)用渲染之前發(fā)生。

Router.map(function() {
  this.route('about');
  this.route('contact');
  this.route('rentals', function() {
      this.route('show', { path: '/:rental_id' });
    });
});

export default Router

雖然 API 是不同的,他們共享”靜態(tài)路由“模式。React Router 4之前也是這樣的模式。

如果要使用React Router,那么你需要忘記這一切!

背景故事

坦白的說,我們非常郁悶,因?yàn)榈诙娌捎昧?React Router。我們感到被API 限制了。認(rèn)識(shí)到我們正在重新實(shí)現(xiàn) React 的一部份(生命周期等),并且它不能符合 React 給我們編寫的用戶界面的心智模型。

一次研究討論會(huì)前,我們正走走過一家酒店的長(zhǎng)走廊。我們相互討論:”如果我們使用在研討論會(huì)中的模式構(gòu)建路由器會(huì)是什么樣?“

動(dòng)態(tài)路由

靜態(tài)路由:任何渲染發(fā)生之前,將申明路由作為應(yīng)用程序初始化一部分。

當(dāng)我們說動(dòng)態(tài)路由,在應(yīng)用程序正在渲染時(shí)發(fā)生的路由,不是運(yùn)行應(yīng)用程序之外的配置或約定中。在React Router 中一切都是一個(gè)組件。下面是一個(gè) API 回顧,看下它如何工作的。

首先,在應(yīng)用頂部

// react-native
import { NativeRouter } from 'react-router-native'

// react-dom
import { BrowserRouter } from 'react-router-dom'

ReactDOM.render((
  <BrowserRouter>
    <App/>
  </BrowserRouter>
), el)

其次,用 Link 組件去鏈接一個(gè)新定位:

const App = () => (
  <div>
    <nav>
      <Link to="/dashboard">Dashboard</Link>
    </nav>
  </div>
)

最后,當(dāng)用戶訪問 /dashboard 時(shí),會(huì)去渲染一個(gè)路由去顯示用戶界面。

const App = () => (
  <div>
    <nav>
      <Link to="/dashboard">Dashboard</Link>
    </nav>
    <div>
      <Route path="/dashboard" component={Dashboard}/>
    </div>
  </div>
)

路由將渲染 <Dashboard {...props}/>,props 是一些路由器特定的東西,看起來像 {match, location, history} 。如果 /dashboard 鏈接不存在,那么路由將呈現(xiàn)為空。這幾乎就是全部了。

嵌套路由

什么情況下用到嵌套路由,比如應(yīng)用左側(cè)邊欄是個(gè)菜單,點(diǎn)擊不同內(nèi)容時(shí),右側(cè)界面對(duì)應(yīng)相應(yīng)一個(gè)路由并且隨著變化。

許多路由有一些概念性的 ”嵌套路由"。如果你已經(jīng)使用過 React Router 4 之前的版本,那么也將知道它是什么。當(dāng)你從一個(gè)靜態(tài)路由配置移到動(dòng)態(tài)的渲染路由,知道怎么做嗎?怎么嵌套一個(gè)div?

const App = () => (
  <BrowserRouter>
    {/* 這里有個(gè)div */}
    <div>
        {/* 路由 */}
        <Route path="/tacos" component={Tacos}/>
    </div>
  </BrowserRouter>
)

// when the url matches `/tacos` this component renders
const Tacos  = ({ match }) => (
  // 有一個(gè)嵌套div
  <div>
    {/* 有一個(gè)嵌套路由,match.url 幫助我們做一個(gè)相對(duì)路徑 */}
    <Route 
        path={match.url + '/carnitas'} 
        component={Carnitas} />
  </div>
)

可以看出,這里并沒有嵌套 API ,路由只是一個(gè)組件而已,就像 div 一樣。所以嵌套一個(gè)路由或 div , 照著這樣做就行了。

響應(yīng)式路由

用戶先導(dǎo)航到 /invoices。應(yīng)用能自適應(yīng)不同尺寸的屏幕,它們有一個(gè)小的適配器,而且能展示它們 invoices 列表和鏈接到 invoice/dashboard。它們可以深度導(dǎo)航。

小屏幕
路由地址: /invoices

+----------------------+
|                      |
|      Dashboard       |
|                      |
+----------------------+
|                      |
|      Invoice 01      |
|                      |
+----------------------+
|                      |
|      Invoice 02      |
|                      |
+----------------------+
|                      |
|      Invoice 03      |
|                      |
+----------------------+
|                      |
|      Invoice 04      |
|                      |
+----------------------+

在一個(gè)大屏幕上,我們想點(diǎn)擊左邊的 Dashboard 就在右邊顯示一個(gè)對(duì)應(yīng)導(dǎo)航的頁面。

大屏幕
路由地址: /invoices/dashboard

+----------------------+---------------------------+
|                      |                           |
|      Dashboard       |                           |
|                      |   Unpaid:             5   |
+----------------------+                           |
|                      |   Balance:   $53,543.00   |
|      Invoice 01      |                           |
|                      |   Past Due:           2   |
+----------------------+                           |
|                      |                           |
|      Invoice 02      |                           |
|                      |   +-------------------+   |
+----------------------+   |                   |   |
|                      |   |  +    +     +     |   |
|      Invoice 03      |   |  | +  |     |     |   |
|                      |   |  | |  |  +  |  +  |   |
+----------------------+   |  | |  |  |  |  |  |   |
|                      |   +--+-+--+--+--+--+--+   |
|      Invoice 04      |                           |
|                      |                           |
+----------------------+---------------------------+

我們思考一下,/invoices 路由地址是適用于兩種屏幕的,在大屏幕上,它是有效路由嗎?它右邊呈現(xiàn)什么內(nèi)容了?

大屏幕
路由地址: /invoices

+----------------------+---------------------------+
|                      |                           |
|      Dashboard       |                           |
|                      |                           |
+----------------------+                           |
|                      |                           |
|      Invoice 01      |                           |
|                      |                           |
+----------------------+                           |
|                      |                           |
|      Invoice 02      |             ???           |
|                      |                           |
+----------------------+                           |
|                      |                           |
|      Invoice 03      |                           |
|                      |                           |
+----------------------+                           |
|                      |                           |
|      Invoice 04      |                           |
|                      |                           |
+----------------------+---------------------------+

在大屏幕上,/invoices 不是有效路由,但是在小屏幕上是有效路由。為了讓事件更有趣,考慮一些伙伴會(huì)用大屏手機(jī)。他們先縱向方向?yàn)g覽 /invoices ,然后把手機(jī)轉(zhuǎn)向橫向。突然,頁面上有多余的空間來顯示主界面,所以這里我們需要重定向。

React Router 以前版本的靜態(tài)路由為這種情況是不能有可組合的方案。當(dāng)路由是動(dòng)態(tài)的,無論如何,你能聲明式的編寫這個(gè)功能。如果你開始想U(xiǎn)I想路由,不是像靜態(tài)配置那樣,你的直覺會(huì)引導(dǎo)你到下面的代碼:

const App = () => (
  <AppLayout>
    <Route path="/invoices" component={Invoices}/>
  </AppLayout>
)

const Invoices = () => (
  <Layout>

    {/* 一直顯示的導(dǎo)航 */}
    <InvoicesNav/>

    <Media query={PRETTY_SMALL}>
      {screenIsSmall => screenIsSmall
        // 小屏幕時(shí)沒有重定向
        ? <Switch>
            <Route exact path="/invoices/dashboard" component={Dashboard}/>
            <Route path="/invoices/:id" component={Invoice}/>
          </Switch>
        // 大屏幕時(shí)重定向!
        : <Switch>
            <Route exact path="/invoices/dashboard" component={Dashboard}/>
            <Route path="/invoices/:id" component={Invoice}/>
            // 重定向
            <Redirect from="/invoices" to="/invoices/dashboard"/>
          </Switch>
      }
    </Media>
  </Layout>
)

隋著用戶的手機(jī)從縱向旋轉(zhuǎn)到橫向,這段代碼將自動(dòng)重定向它們到 dashboard ,這一組有效路由改變?nèi)Q于移動(dòng)設(shè)備在用戶手中的動(dòng)態(tài)狀態(tài)。

這僅是一個(gè)案例。還有很多其他可以討論的,我們總結(jié)的建議:為了讓你理解React Router ,想想它是組件,不是一個(gè)靜態(tài)路由,思考如何用 React 聲明性可組合性解決問題,因?yàn)閹缀趺總€(gè)"React Router 問題"大概是個(gè)”React 問題“。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,733評(píng)論 25 709
  • React-Router v4 1. 設(shè)計(jì)理念1.1. 動(dòng)態(tài)路由1.2. 嵌套路由1.3. 響應(yīng)式路由 2. 快速...
    wlszouc閱讀 8,703評(píng)論 0 14
  • React Router v4 發(fā)布已經(jīng)有幾個(gè)月了,但好像并沒有得到太多人的青睞,大家(包括我們團(tuán)隊(duì)自己)還是習(xí)慣...
    艾特老干部閱讀 3,653評(píng)論 5 15
  • React Router 4.0 (以下簡(jiǎn)稱 RR4) 已經(jīng)正式發(fā)布,它遵循React的設(shè)計(jì)理念,即萬物皆組件。所...
    梁相輝閱讀 98,036評(píng)論 24 195
  • 文|崔藝馨 這是繼《遇見未知的自己》讀到的張德芬的第二部作品,也是身心靈三部曲之一。身心靈發(fā)展的過程分為三個(gè)階段,...
    崔藝馨閱讀 635評(píng)論 0 0

友情鏈接更多精彩內(nèi)容