React.jsと組み合わせるfluxのライブラリreduxを試してみた。 このページは作業ログです。やったことをつらつら書くだけなのでまとめません。あしからず。
対象読者
- 主に自分
今日のゴール
- redux-react-routerを使ってページ切り替えを実現する
redux-react-routerとは?
Reactのラウター(ルーターではない)ライブラリとしてよくreact-routerが使われる。react-routerの機能は十分だが、現在表示しているページという"状態"がアプリケーションに登場する。これもできればstoreに押し込めたい。ということで登場したライブラリ。react-routerをベースにしたライブラリなので、まずreact-routerから見ていく。
react-routerの特徴
ドキュメントの構造とURLの構造をマッピングするライブラリ。最初ドキュメントを読んだ時理解できなかったけどこんなことらしい。端的に言えば、画面上のコンポーネントをURLによって切り替えたい部分毎に<Route>
を用意し、対応するcomponentを下記のように定義しておくと、URLがマッチする時にコンポーネントを切り替えてくれる。Routeの定義は下記のようになるだろう。
<Route path="/" component="App">
<IndexRoute component="Home">
<Route path="home" component="Home"/>
<Route path="profile" component="Profile"/>
</Route>
<IndexRoute>
とは、親のコンポーネントに指定したURLにアクセスしたらレンダリングしたいデフォルトのコンポーネントを指定するためのタグである。上記の例では/
にアクセスするとApp
とHome
がレンダリングされる。それぞれのコンポーネントが下記のように定義されていたとしよう。
import {Component} from 'react';
import {TopMenu} from '../components/TopMenu';
class App extends Component {
render() {
return (
<div>
<TopMenu />
{this.props.children}
</div>
);
}
}
import {Component} from 'react';
class Home extends Component {
render() {
return (
<div>
<H2>Home</H2>
<section>ここはHomeだよ。</section>
{this.props.children}
</div>
);
}
}
import {Component} from 'react';
class Profile extends Component {
render() {
return (
<div>
<H2>Profile</H2>
<section>ここはProfileだよ。</section>
{this.props.children}
</div>
);
}
}
/
もしくは/home
にアクセスすると、Routeの指定により、下記の構造でレンダリングされる。
<App>
<Home />
</App>
/profile
にアクセスしたとすると、下記のように切り替わる。
<App>
<Profile />
</App>
切り替えを行うリンクを作成するのは、<Link>
である。下記のように利用する。
import {Link} from 'react-router';
...
<Link to='/home'>Home</Link>
例題:現在開いているURLをページ上に出す
画面が遷移できるようになってきたので、試しにURLの変更をUI上に出してみる。下記のように、@connect()
でstateの変更を拾えばOK。
@connect(state => ({ routerState: state.router,
currentLocation : state.router.location.pathname
}))
class Root extends Component {
render() {
const {currentLocation,children} = this.props;
return (
<div>
<TopMenu/>
<div className="page-header">
<h1>{currentLocation}</h1>
</div>
{children}
</div>
</div>
);
}
}
下記の3行がデータバインディング的な箇所。
@connect(state => ({ routerState: state.router,
currentLocation : state.router.location.pathname
}))
redux-devtools
を入れておくと、現在のstateの構造がわかるから、それを見て必要そうな状態を拾い上げる。
参考URL
-
React初心者のためのreact-routerの使い方 注: react-routerのバージョンアップにより、
handler
ではなくcomponent
を指定するようになってきた模様