ReactとHistory APIを使ってrouterを自作する

概要

準備

まずはHistory APIを理解しておきます。GO TO MDN。

忙しい人はpushStatewindow.popstateだけ理解しておけばなんとかなるはず。

仕様

このrouterでは、以下のようなURLに対応します。

  • /post
  • /post/:id
  • /post/:id/:title

クエリパラメータには対応しません。

使用するパッケージ

React周りは省略します。

React以外で使うパッケージは1つだけです。

pillarjs/path-to-regexp

URL部分の正規表現を良しなにやってくれるパッケージです。

そのうち自分で正規表現書きたいですが、今回はパッケージに頼っちゃいます。

実装

ナビゲーションとページに対応するコンポーネントを作成

ナビゲーション、ナビゲーションにそれぞれ対応するコンポーネントを用意しておきます。

ルーティングの実装

ルーティングを実装していきます。

コンポーネントは、RouterRouteという2つを用意します。

RouterはURLに応じて描画切り替えを行うコンポーネントです。

Routeはaタグをラップしただけのコンポーネントです。

それからルーティング規約を記述するファイルとして、routes.jsを用意します。

routes.jsはパスと、パスに対応するコンポーネントの対応をオブジェクトの配列で記述したものです。

ここまででおおよそ察しがつくかと思いますが、ルーティングの一連の処理としては、

初期状態(ファーストビュー) ①現在のURL情報を取得 ②現在のURL情報に一致するコンポーネントを描画

URL情報をStateとして持ちます。

遷移 ①クリックされたリンクのパスを取得 ②History APIのpushStateで履歴を追加・遷移 ③コンポーネントを再描画

Stateが更新され、コンポーネントが再描画されます。

各コンポーネントの実装はこんな感じです。

Route.js

Router.js

routes.js

App.js

※jsxの改行がなんか変なのは多分eslintをちゃんと設定していないからだと思います...

You might not need React Router を結構参考にしました。

実装する上で厄介だった部分は、「パラメータ(:id)の情報をどうやって取得するか、保持するか」という点でしたが、path-to-regexpというawesomeなライブラリのおかげで、その点は克服できました。

Github

今回のソース置いておきます。

bmf-san/rubel-router

npmにも公開しています。

rubel-router

所感

EventEmitterやObserverをつかったらもっと綺麗になる気が・・(勉強不足)

参考

参考記事

参考ソース