React-router-redux

對於網站開發來說,Router是最必須要的部分。
以前一般來說我們會在server上發一個request給server,
server透過router指向到對應的資源,
將內容傳回給clinet(browser)

而用原生的window.history提供的方法,可以讓你用js操作你的url,歷史紀錄,再配合上ajax的方法,就可以實現換部分頁面內容不全部刷新的功能。當然在剛進這個網址時js也要做處理,將網址的參數帶入ajax去做讀取資料的動作。

現在我們用React做Single Page Application (SPA)
而通常用webpack將React的程式打包成一個js檔,通常這樣就包含了所有的畫面元素(html和css樣式,可能也包括靜態資料),而其實在進入這個頁面時再透過ajax(或fetch)將json資料抓回來呈現。

有點像在寫應用程式,不是嗎?只是安裝的步驟變成了下載一個js檔而已,相當的方便。

React-router

在React上我們通常用React-router來處理路由方面的動作 大致像如下的設定

<Router history={history}>
     <Route component={App}>
      <Route path="/" component={Recipe} />
      <Route path="/home" component={Home} />
      <Route path="/recipes" component={Recipe} />
      <Route path="/recipes/search" component={Recipe} />
      <Route path="/recipes/:id" component={RecipeShow} />

      <Route path="/messages" component={Message} />
      <Route path="/messages/new" component={MessageNew} />
      <Route path="/messages/:id" component={MessageShow} />

      <Route path="/users/favorites" component={UserFavorites} />
      <Route path="/users/edit" component={UserEdit} />
  {/*     <Route path="/users/edit_password" component={UserEditPassword} />*/}

      <Route path="login" component={Login} />
      <Route path="register" component={Register} />
      <Route path="dashboard" component={requireAuthentication(Dashboard)} />
      <Route path="about" component={About} />
      <Route path="privacy" component={Privacy} />
  </Route>
    </Router>

當你透過React-router的語法,像是

import { Link } from 'react-router'
<Link to={`/user/${user.id}`}>{user.name}</Link>

而不是用來產生連結時,react-router會幫你控制路由,於是你就可以開始做單頁式應用(SPA)程式,並且透過類似url的方式來切換不同的頁面。

但想要做到直接輸入網址就要呈現內容的話,還是得做Server render部分的處理。

React-router-redux

由於我們使用redux做為開發,也想要把路由納入redux store的管理之下,怎麼做呢?

https://github.com/reactjs/react-router-redux
當然還是參考官網的做法比較好(因為隨著版本不同設定都可能有變
但大致上來說是:

  • 將routerReducer放進reduxer.
  • 將store的history和browser的history同步(這邊在v4.0.0)是用syncHistoryWithStore.
  • 將產生出來的history物件放進react-router裡。
  • 將routerMiddleware放入applyMiddleware內

如此之後,我取網址的參數的做法如下(用es7的decorate)

@connect((state, ownProps) => ({
  path: ownProps.location.pathname + ownProps.location.search,
  params: ownProps.location.query
}))

path可以取到整段網址 params可以取到每個參數的值

那如果要換網址的時候呢 連結還是用react-router的Link

在程式裡面可以用

push(location)到某網址, replace(location)更換本頁的歷史紀錄, go(number)前幾頁, goBack()前一頁, goForward()下一頁

一般用push可能就夠用了。

這樣路由部分就搞定囉。