ページ内画面遷移を実装する
開発環境が整ったところで、いよいよTODOアプリを仕上げていきましょう。その前に、アプリの仕様を再確認しておきます。
- トップページで新規TODOを登録する
- Doneボタンを押下するとTODOが完了状態になる
- 未完了のTODOはトップページ(#active)に、完了済のTODOは2ページ目(#completed)に表示する
まだトップページしか作っていませんので、まずは2ページ目に遷移できるようにしましょう。
シングルページアプリケーションにおけるRouterの概念
シングルページアプリケーションでは同一ページ内で画面を再描画するため、そのままではURLが切り替わらず、戻る・進むボタンなどの操作やブックマークができず不便です。そこで、多くのJavaScriptフレームワークではRouterと呼ばれる仕組みを用いて、URLを切り替えながらページ内の画面遷移を実現しています。これは、ちょうどサーバがリクエストされたURLに応じて処理を振り分ける動作を、クライアント側で再現したものです。
注意点としては、例えば/から/fooにページ内で画面遷移する場合と、/fooに直接アクセスする場合とで、同じ画面が表示される必要があります。Routerが正しく機能しているかを確かめるには、次の操作を試してみてください。
- ブラウザの「戻る」「進む」「更新」ボタンを押したときにコンテンツが正しく切り替わる
- 新しいタブにURLをコピーしたときに同じ内容が表示される
サンプルではサーバー側の実装を省略するため、ハッシュリンクを使って画面を切り替える方式を採用しています[6]。
[6] ハッシュを用いる場合Routerの実装はhashchangeイベントを利用し、ハッシュを用いない場合Routerの実装はHTML5のpushState()/popState()を利用します。表面的なRouterの使い方はどちらも変わりません。
Routerを使ってページ遷移を実装する
React.jsはViewのみを扱うため、それ自体はRouterの機能を持っていませんが、外部ライブラリを使うことで、Router機能を容易に実現できます。ここでは、Routerライブラリの1つである「director」を使います。
var Router = require('director').Router;
...
var App = React.createClass({
...
componentDidMount: function() {
...
var setActivePage = function() {
this.setState({ page: 'active'});
}.bind(this);
var setCompletedPage = function() {
this.setState({ page: 'completed' });
}.bind(this);
var router = Router({
'/active': setActivePage,
'/completed': setCompletedPage,
'*': setActivePage,
});
router.init();
},
render: function() {
var page = this.state.page === 'active' ?
<TodoList todos={this.state.todos}/> :
<div>Completed todos comes here!</div>;//TODO replace with <CompletedTodoList>
return (
<div>
<h1>My Todo</h1>
<ul>
<li><a href="#/active">Active</a></li>
<li><a href="#/completed">Completed</a></li>
</ul>
{page}
</div>
);
}
});
/activeと/completedへの遷移(実際にはハッシュが付く)を検知してthis.stateを更新し、それぞれの内容をレンダリングします。デフォルトでは/activeと同じページが表示されるようにしています。
これで画面遷移を実現することができました。あとは、上でTODOになっているコンポーネントを実装すれば完了です。次ページからは、React.jsを使って開発をする上で役立つTipsを紹介します。
