summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/js/package.json4
-rw-r--r--src/main/js/src/containers/App/index.js2
-rw-r--r--src/main/js/src/containers/Counter/actions.js20
-rw-r--r--src/main/js/src/containers/Counter/constants.js4
-rw-r--r--src/main/js/src/containers/Counter/index.js51
-rw-r--r--src/main/js/src/containers/Counter/reducer.js17
-rw-r--r--src/main/js/src/containers/Counter/saga.js14
-rw-r--r--src/main/js/src/index.js5
-rw-r--r--src/main/js/src/reducers.js7
-rw-r--r--src/main/js/src/sagas.js7
-rw-r--r--src/main/js/src/store.js15
-rw-r--r--src/main/js/yarn.lock23
12 files changed, 163 insertions, 6 deletions
diff --git a/src/main/js/package.json b/src/main/js/package.json
index 46281613..30ecc9e2 100644
--- a/src/main/js/package.json
+++ b/src/main/js/package.json
@@ -6,11 +6,13 @@
"react-scripts": "0.8.3"
},
"dependencies": {
+ "babel-polyfill": "^6.20.0",
"react": "^15.4.1",
"react-dom": "^15.4.1",
"react-redux": "^5.0.1",
"react-router": "4.0.0-alpha.6",
- "redux": "^3.6.0"
+ "redux": "^3.6.0",
+ "redux-saga": "^0.13.0"
},
"scripts": {
"start": "react-scripts start",
diff --git a/src/main/js/src/containers/App/index.js b/src/main/js/src/containers/App/index.js
index 507c01ae..b190f960 100644
--- a/src/main/js/src/containers/App/index.js
+++ b/src/main/js/src/containers/App/index.js
@@ -3,6 +3,8 @@ import { Link } from 'react-router'
export default () => {
return <div>
<h1>Hello World</h1>
+ <Link to="/counter">Go to counter +/-</Link>
+ <br/>
<Link to="/404">Go to 404</Link>
</div>
} \ No newline at end of file
diff --git a/src/main/js/src/containers/Counter/actions.js b/src/main/js/src/containers/Counter/actions.js
new file mode 100644
index 00000000..01cd8d67
--- /dev/null
+++ b/src/main/js/src/containers/Counter/actions.js
@@ -0,0 +1,20 @@
+import {
+ INCREMENT, DECREMENT,
+ INCREMENT_IF_ODD, INCREMENT_ASYNC
+} from './constants'
+
+export const increment = () => ({
+ type: INCREMENT
+})
+
+export const decrement = () => ({
+ type: DECREMENT
+})
+
+export const incrementIfOdd = () => ({
+ type: INCREMENT_IF_ODD
+})
+
+export const incrementAsync = () => ({
+ type: INCREMENT_ASYNC
+}) \ No newline at end of file
diff --git a/src/main/js/src/containers/Counter/constants.js b/src/main/js/src/containers/Counter/constants.js
new file mode 100644
index 00000000..9b829ae0
--- /dev/null
+++ b/src/main/js/src/containers/Counter/constants.js
@@ -0,0 +1,4 @@
+export const INCREMENT = 'counter/INCREMENT'
+export const DECREMENT = 'counter/DECREMENT'
+export const INCREMENT_IF_ODD = 'counter/INCREMENT_IF_ODD'
+export const INCREMENT_ASYNC = 'counter/INCREMENT_ASYNC' \ No newline at end of file
diff --git a/src/main/js/src/containers/Counter/index.js b/src/main/js/src/containers/Counter/index.js
new file mode 100644
index 00000000..a91af8f5
--- /dev/null
+++ b/src/main/js/src/containers/Counter/index.js
@@ -0,0 +1,51 @@
+import React, { PropTypes } from 'react'
+import { connect } from 'react-redux'
+
+import {
+ increment,
+ decrement,
+ incrementAsync,
+ incrementIfOdd
+} from './actions'
+
+const Counter = ({ value, increment, decrement, incrementIfOdd, incrementAsync }) =>
+ <p>
+ Clicked: {value} times
+ {' '}
+ <button onClick={increment}>
+ +
+ </button>
+ {' '}
+ <button onClick={decrement}>
+ -
+ </button>
+ {' '}
+ <button onClick={incrementIfOdd}>
+ Increment if odd
+ </button>
+ {' '}
+ <button onClick={incrementAsync}>
+ Increment async
+ </button>
+ </p>
+
+Counter.propTypes = {
+ value: PropTypes.number.isRequired,
+ increment: PropTypes.func.isRequired,
+ decrement: PropTypes.func.isRequired,
+ incrementAsync: PropTypes.func.isRequired,
+ incrementIfOdd: PropTypes.func.isRequired
+}
+
+const mapStateToProps = (state) => ({
+ value: state.counter
+})
+
+const mapDispatchToProps = {
+ increment,
+ decrement,
+ incrementAsync,
+ incrementIfOdd
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Counter) \ No newline at end of file
diff --git a/src/main/js/src/containers/Counter/reducer.js b/src/main/js/src/containers/Counter/reducer.js
new file mode 100644
index 00000000..586c4e0a
--- /dev/null
+++ b/src/main/js/src/containers/Counter/reducer.js
@@ -0,0 +1,17 @@
+import {
+ INCREMENT, DECREMENT,
+ INCREMENT_IF_ODD
+} from './constants'
+
+export default function reducer(state = 0, action) {
+ switch (action.type) {
+ case INCREMENT:
+ return state + 1
+ case DECREMENT:
+ return state - 1
+ case INCREMENT_IF_ODD:
+ return (state % 2 === 0) ? state + 1 : state
+ default:
+ return state
+ }
+} \ No newline at end of file
diff --git a/src/main/js/src/containers/Counter/saga.js b/src/main/js/src/containers/Counter/saga.js
new file mode 100644
index 00000000..fe210620
--- /dev/null
+++ b/src/main/js/src/containers/Counter/saga.js
@@ -0,0 +1,14 @@
+import { put, call } from 'redux-saga/effects'
+import { delay, takeEvery } from 'redux-saga'
+
+import { increment } from './actions'
+import { INCREMENT_ASYNC } from './constants'
+
+export function* incrementAsync() {
+ yield call(delay, 1000)
+ yield put(increment())
+}
+
+export default function* counterSaga() {
+ yield takeEvery(INCREMENT_ASYNC, incrementAsync)
+} \ No newline at end of file
diff --git a/src/main/js/src/index.js b/src/main/js/src/index.js
index f2be8a53..926c756a 100644
--- a/src/main/js/src/index.js
+++ b/src/main/js/src/index.js
@@ -1,3 +1,5 @@
+import 'babel-polyfill'
+
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter, Match, Miss } from 'react-router'
@@ -9,12 +11,15 @@ const store = configureStore(initialState)
import './global-styles.css'
import App from './containers/App'
+import Counter from './containers/Counter'
import Error404 from './components/errors/Error404'
+
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<div className="app">
<Match exactly pattern="/" component={App} />
+ <Match exactly pattern="/counter" component={Counter}/>
<Miss component={Error404} />
</div>
</BrowserRouter>
diff --git a/src/main/js/src/reducers.js b/src/main/js/src/reducers.js
index fceaf07c..82540b00 100644
--- a/src/main/js/src/reducers.js
+++ b/src/main/js/src/reducers.js
@@ -1,5 +1,8 @@
-import { combineReducer } from 'redux'
+import { combineReducers } from 'redux'
+import counterReducer from './containers/Counter/reducer'
export default function createReducer() {
- return () => ({})
+ return combineReducers({
+ counter: counterReducer
+ })
} \ No newline at end of file
diff --git a/src/main/js/src/sagas.js b/src/main/js/src/sagas.js
new file mode 100644
index 00000000..80222362
--- /dev/null
+++ b/src/main/js/src/sagas.js
@@ -0,0 +1,7 @@
+import { fork } from 'redux-saga/effects'
+
+import counterSaga from './containers/Counter/saga'
+
+export default function* rootSaga() {
+ yield fork(counterSaga)
+} \ No newline at end of file
diff --git a/src/main/js/src/store.js b/src/main/js/src/store.js
index d4885275..bbeb51bd 100644
--- a/src/main/js/src/store.js
+++ b/src/main/js/src/store.js
@@ -1,11 +1,18 @@
-import { createStore, compose } from 'redux'
+import { createStore, applyMiddleware, compose } from 'redux'
import createReducer from './reducers'
+import createSagaMiddleware from 'redux-saga'
+import rootSaga from './sagas'
export default function configureStore(initialState = {}) {
- const middlewares = []
+ const sagaMiddleware = createSagaMiddleware()
+
+ const middlewares = [
+ sagaMiddleware
+ ]
const enhancers = [
+ applyMiddleware(...middlewares)
]
const composeEnhancers =
@@ -20,5 +27,7 @@ export default function configureStore(initialState = {}) {
composeEnhancers(...enhancers)
)
+ sagaMiddleware.run(rootSaga)
+
return store
-} \ No newline at end of file
+}
diff --git a/src/main/js/yarn.lock b/src/main/js/yarn.lock
index c3f32431..983f930a 100644
--- a/src/main/js/yarn.lock
+++ b/src/main/js/yarn.lock
@@ -736,6 +736,14 @@ babel-plugin-transform-strict-mode@^6.18.0:
babel-runtime "^6.0.0"
babel-types "^6.18.0"
+babel-polyfill:
+ version "6.20.0"
+ resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.20.0.tgz#de4a371006139e20990aac0be367d398331204e7"
+ dependencies:
+ babel-runtime "^6.20.0"
+ core-js "^2.4.0"
+ regenerator-runtime "^0.10.0"
+
babel-preset-env@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-0.0.8.tgz#a7e37e4b345263d045cd29738a0aff1ce31f5b0e"
@@ -874,6 +882,13 @@ babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.9.0, babel-runtime
core-js "^2.4.0"
regenerator-runtime "^0.9.5"
+babel-runtime@^6.20.0:
+ version "6.20.0"
+ resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.20.0.tgz#87300bdcf4cd770f09bf0048c64204e17806d16f"
+ dependencies:
+ core-js "^2.4.0"
+ regenerator-runtime "^0.10.0"
+
babel-runtime@6.11.6:
version "6.11.6"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.11.6.tgz#6db707fef2d49c49bfa3cb64efdb436b518b8222"
@@ -4374,10 +4389,18 @@ redux:
loose-envify "^1.1.0"
symbol-observable "^1.0.2"
+redux-saga:
+ version "0.13.0"
+ resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-0.13.0.tgz#9294386550deb0d56bc9a1b3c90a613e7ddb6593"
+
regenerate@^1.2.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
+regenerator-runtime@^0.10.0:
+ version "0.10.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.1.tgz#257f41961ce44558b18f7814af48c17559f9faeb"
+
regenerator-runtime@^0.9.5:
version "0.9.6"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029"
bgstack15