diff options
-rw-r--r-- | src/main/js/package.json | 4 | ||||
-rw-r--r-- | src/main/js/src/containers/App/index.js | 2 | ||||
-rw-r--r-- | src/main/js/src/containers/Counter/actions.js | 20 | ||||
-rw-r--r-- | src/main/js/src/containers/Counter/constants.js | 4 | ||||
-rw-r--r-- | src/main/js/src/containers/Counter/index.js | 51 | ||||
-rw-r--r-- | src/main/js/src/containers/Counter/reducer.js | 17 | ||||
-rw-r--r-- | src/main/js/src/containers/Counter/saga.js | 14 | ||||
-rw-r--r-- | src/main/js/src/index.js | 5 | ||||
-rw-r--r-- | src/main/js/src/reducers.js | 7 | ||||
-rw-r--r-- | src/main/js/src/sagas.js | 7 | ||||
-rw-r--r-- | src/main/js/src/store.js | 15 | ||||
-rw-r--r-- | src/main/js/yarn.lock | 23 |
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" |