前回は 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 に触れます。