React tutorial (6)
前回は react での routing について触れました。 今回は HTTP 通信が成功した時などに表示する Notification (Flash Message) に触れます。
Notification も色々あるのですが豊富な機能を備えた reapop
を紹介します。
目次
- 開発環境を準備
- React の基本的な Life Cycle に触れる
- redux に触れる
- redux-saga に触れる
- react router に触れる
- npm で公開されている components を導入して echo system を体感する <= 今日やること
- redux-form に触れる
- react-select に触れる
今日やること
準備
依存モジュールを install します。 redux-thunk
は reapop が使うので install しますが今回のチュートリアルでは自身で実装する箇所はありません。
npm install --save redux-thunk font-awesome reapop reapop-theme-wybo
各種ファイル
edit src/store/configureStore.js
import { createStore, applyMiddleware } from 'redux' import { reducer as notificationsReducer } from 'reapop' import createSagaMiddleware from 'redux-saga' import createLogger from 'redux-logger' import thunk from 'redux-thunk' import rootReducers from '../reducers' import rootSaga from "../sagas" const sagaMiddleware = createSagaMiddleware() const logger = createLogger() const middleware = [thunk, sagaMiddleware, logger] const createStoreWithMiddleware = applyMiddleware(...middleware)(createStore) export default function configureStore(initialState) { const store = createStoreWithMiddleware(rootReducers, initialState) if (module.hot) { module.hot.accept('../reducers', () => { const nextRootReducer = require('../reducers').default store.replaceReducer(nextRootReducer) }) } sagaMiddleware.run(rootSaga) return store }
edit src/reducers/index.js
import { combineReducers } from 'redux' import { routerReducer } from 'react-router-redux' import { reducer as notificationsReducer } from 'reapop' 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({ notifications: notificationsReducer(), fetch, routing: routerReducer, }) export default rootReducer
edit src/containers/Posts.js
import React, {Component} from 'react' import { connect } from 'react-redux' import Notifications from 'reapop' import theme from 'reapop-theme-wybo' import { fetchRequest } from '../actions' import { PostItem } from '../components/Posts' import { getPosts } from '../actions' class Posts extends Component { handleButtonClick() { this.props.dispatch(getPosts({userId: 1})) } render() { const {posts} = this.props.fetch return ( <div className="container"> <Notifications theme={theme}/> <h2>Posts</h2> {posts.map((post) => ( <PostItem key={post.id} post={post} /> ))} <button className="btn btn-default" onClick={this.handleButtonClick.bind(this)}>Push</button> </div> ) } } const select = state => (state) export default connect(select)(Posts)
edit src/sagas.js
import { takeEvery } from "redux-saga" import { put, call } from "redux-saga/effects" import { addNotification as notify } from 'reapop' import { FETCH_REQUESTED, fetchSuccessed, fetchFailed, } from "./actions" function notifySuccess(message) { return notify({ message, position: 'tc', status: 'success', dismissAfter: 3000 }) } function notifyError(message) { return notify({ message, position: 'tc', status: 'error', dismissAfter: 3000 }) } function* fetch(action) { try { const data = yield call(action.payload) yield put(fetchSuccessed(data)) yield put(notifySuccess("fetch success")) } catch (err) { yield put(fetchFailed(err)) yield put(notifyError(err.message)) } } export default function* rootSaga() { yield takeEvery(FETCH_REQUESTED, fetch) }
説明
fetch が成功したらメッセージを表示させます。
今回の tutorial ではこのような書き方をしていますが、 redux-saga を使っているので FETCH_SUCCESSED
と FETCH_FAILED
を検知して動作させることもできます。
次回は redux-form に触れます。