あいつの日誌β

働きながら旅しています。

React tutorial (5)

前回は React で Single Page Application をするためによく使われる redux-saga に触れました。 今回もよく使われる機能である react-router に触れます。

目次

  • 開発環境を準備
  • React の基本的な Life Cycle に触れる
  • redux に触れる
  • redux-saga に触れる
  • react router に触れる <= 今日やること
  • npm で公開されている components を導入して echo system を体感する
  • redux-form に触れる
  • react-select に触れる

準備

react-router と一緒に react-router-redux を install します。

npm install --save react-router react-router-redux

各種ファイル作成

touch src/containers/App.js src/containers/Home.js

create src/containers/App.js

import React, { Component } from 'react'
import { Link } from 'react-router'
import { connect } from 'react-redux'

class App extends Component {

  render() {
    return (
      <div className="container">
        <h1>Single Page Application</h1>
        <p><Link to="/">Home</Link> | <Link to="/posts">Posts</Link></p>
        <div style={{ marginTop: '1.5em' }}>{this.props.children}</div>
      </div>
    )
  }
}

export default connect(state => (state))(App)

create src/components/Home.js

import React, { Component } from 'react'
import { connect } from 'react-redux'

class Home extends Component {

  render() {
    return (
      <div>
        <h2>Home</h2>
        <p>this is Home.js</p>
      </div>
    )   
  }
}

export default connect(state => (state))(Home)

edit src/Root.js

import 'babel-polyfill'
import 'bootstrap'
import 'bootstrap/dist/css/bootstrap.css'
import React from 'react'
import { Provider } from 'react-redux'
import { Router, Route, IndexRoute, browserHistory } from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'

import configureStore from './store/configureStore'
import App from './containers/App'
import Home from './containers/Home'
import Posts from './containers/Posts'

const store = configureStore()
const history = syncHistoryWithStore(browserHistory, store)

const NotFound = () => (<div><span>NOT FOUND</span></div>)

export default (props) => (
  <Provider store={store}>
    <Router history={history}>
      <Route path="/" component={App}>
        <IndexRoute component={Home} />
        <Route path="posts" component={Posts} />
      </Route>
      <Route path="*" component={NotFound}/>
    </Router>
  </Provider>
)

edit src/reducers/index.js

import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux'

import { FETCH_SUCCESSED } from '../actions'

const fetchInitialState = {
  posts: []
}

function fetch(state = fetchInitialState, action) {
  switch (action.type) {
  case FETCH_SUCCESSED:
    return Object.assign({}, state, action.payload)
  default:
    return state
  }
}

const rootReducer = combineReducers({
  fetch,
  routing: routerReducer,
})

export default rootReducer

以下を実行

% node devServer.js

説明

ここでは App.js が template の layout を担当しています。 Navigator のような共通パーツを親コンポーネントに配置して、子となるコンポーネントを URL に応じて振り分けて表示させます。 ここでは紹介しませんが親、子、孫と伝播させることも可能です。

まとめ

今回は Single Page Application の Routing を紹介しました。 次回は npm で利用できる notification を紹介します。