Skip to content

Commit f3f095b

Browse files
committed
add redux-saga
1 parent cc9f6ba commit f3f095b

File tree

9 files changed

+53
-12
lines changed

9 files changed

+53
-12
lines changed

config/_base.js

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const config = {
3737
colors : true
3838
},
3939
compiler_vendor : [
40+
'babel-polyfill',
4041
'classnames',
4142
'history',
4243
'immutable',

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@
6464
"author": "David Zukowski <david@zuko.me> (http://zuko.me)",
6565
"license": "MIT",
6666
"dependencies": {
67+
"babel-polyfill": "6.5.0",
6768
"better-npm-run": "0.0.7",
68-
"classnames": "^2.2.3",
69+
"classnames": "2.2.3",
6970
"co-request": "^1.0.0",
7071
"debug": "^2.2.0",
7172
"history": "^2.0.0",
@@ -83,6 +84,7 @@
8384
"react-router-redux": "^4.0.0-beta",
8485
"redux": "^3.0.0",
8586
"redux-immutable": "3.0.5",
87+
"redux-saga": "0.9.1",
8688
"redux-thunk": "^1.0.0",
8789
"url": "^0.11.0",
8890
"yargs": "^4.1.0"

src/layouts/CoreLayout/CoreLayout.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { PropTypes } from 'react';
22
import 'normalize.css';
3+
34
import '../../styles/core.css';
45

56
// Note: Stateless/function components *will not* hot reload!

src/main.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import 'babel-polyfill';
12
import React from 'react';
23
import ReactDOM from 'react-dom';
34
import createBrowserHistory from 'history/lib/createBrowserHistory';
45
import { useRouterHistory } from 'react-router';
56
import { syncHistoryWithStore } from 'react-router-redux';
7+
68
import makeRoutes from './routes';
79
import Root from './containers/Root';
810
import configureStore from './redux/configureStore';

src/redux/configureStore.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import { Map } from 'immutable';
22
import { applyMiddleware, compose, createStore } from 'redux';
33
import thunk from 'redux-thunk';
4+
import createSagaMiddleware from 'redux-saga';
45

56
import rootReducer from './rootReducer';
7+
import { rootSaga } from './sagas';
68

79
export default function configureStore (initialState = new Map()) {
810
// Compose final middleware and use devtools in debug environment
9-
let middleware = applyMiddleware(thunk);
11+
let middleware = applyMiddleware(
12+
createSagaMiddleware(rootSaga),
13+
thunk
14+
);
1015
if (__DEBUG__) {
1116
const devTools = window.devToolsExtension
1217
? window.devToolsExtension()

src/redux/modules/counter.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Constants
33
// ------------------------------------
44
export const COUNTER_INCREMENT = 'COUNTER_INCREMENT';
5+
export const COUNTER_TRIPLE = 'COUNTER_TRIPLE';
56

67
// ------------------------------------
78
// Actions
@@ -28,9 +29,12 @@ export const doubleAsync = () => {
2829
};
2930
};
3031

32+
export const tripleSaga = () => ({ type: COUNTER_TRIPLE });
33+
3134
export const actions = {
3235
increment,
33-
doubleAsync
36+
doubleAsync,
37+
tripleSaga
3438
};
3539

3640
// ------------------------------------

src/redux/sagas/index.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { takeEvery } from 'redux-saga';
2+
import { fork, put, select } from 'redux-saga/effects';
3+
4+
import { COUNTER_TRIPLE, increment } from '../modules/counter';
5+
6+
function * counterTriple () {
7+
let counter = yield select((state) => state.get('counter'));
8+
yield put(increment(counter * 2));
9+
}
10+
11+
function * watchCounterTriple () {
12+
while (true) {
13+
yield * takeEvery(COUNTER_TRIPLE, counterTriple);
14+
}
15+
}
16+
17+
export function * rootSaga () {
18+
yield [
19+
fork(watchCounterTriple)
20+
];
21+
}

src/views/HomeView/HomeView.js

+13-9
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,14 @@ import React, { PropTypes } from 'react';
22
import { connect } from 'react-redux';
33
import classnames from 'classnames';
44

5-
import { increment, doubleAsync } from '../../redux/modules/counter';
5+
import { increment, doubleAsync, tripleSaga } from '../../redux/modules/counter';
66
import DuckImage from './Duck.jpg';
77
import classes from './HomeView.css';
88

99
// We avoid using the `@connect` decorator on the class definition so
1010
// that we can export the undecorated component for testing.
1111
// See: http://rackt.github.io/redux/docs/recipes/WritingTests.html
1212
export class HomeView extends React.Component {
13-
static propTypes = {
14-
counter: PropTypes.number.isRequired,
15-
doubleAsync: PropTypes.func.isRequired,
16-
increment: PropTypes.func.isRequired
17-
};
18-
1913
render () {
2014
return (
2115
<div className='container text-center'>
@@ -35,19 +29,29 @@ export class HomeView extends React.Component {
3529
<button className='btn btn-default' onClick={this.props.increment}>
3630
Increment
3731
</button>
38-
{' '}
3932
<button className='btn btn-default' onClick={this.props.doubleAsync}>
4033
Double (Async)
4134
</button>
35+
<button className='btn btn-default' onClick={this.props.tripleSaga}>
36+
Triple (Saga)
37+
</button>
4238
</div>
4339
);
4440
}
4541
}
4642

43+
HomeView.propTypes = {
44+
counter: PropTypes.number.isRequired,
45+
doubleAsync: PropTypes.func.isRequired,
46+
increment: PropTypes.func.isRequired,
47+
tripleSaga: PropTypes.func.isRequired
48+
};
49+
4750
const mapStateToProps = (state) => ({
4851
counter: state.get('counter')
4952
});
5053
export default connect((mapStateToProps), {
5154
increment: () => increment(1),
52-
doubleAsync
55+
doubleAsync,
56+
tripleSaga
5357
})(HomeView);

tests/test-bundler.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// ---------------------------------------
22
// Test Environment Setup
33
// ---------------------------------------
4+
import 'babel-polyfill';
45
import sinon from 'sinon';
56
import chai from 'chai';
67
import sinonChai from 'sinon-chai';

0 commit comments

Comments
 (0)