Skip to content
This repository has been archived by the owner on Jan 2, 2018. It is now read-only.

Commit

Permalink
Merge pull request #34 from rocjs/feature/redux-saga-support
Browse files Browse the repository at this point in the history
redux-saga support
  • Loading branch information
dlmr authored Oct 13, 2016
2 parents 518f9c5 + 92c54c9 commit 86b481b
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 5 deletions.
1 change: 1 addition & 0 deletions examples/complex/roc.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
koaMiddlewares: 'src/koa-middlewares.js',
redux: {
middlewares: 'src/middlewares.js',
sagas: 'src/sagas.js',
},
reducers: 'src/reducers.js',
routes: 'src/routes.js',
Expand Down
1 change: 1 addition & 0 deletions examples/complex/src/components/about/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { provideHooks } from 'redial';
}),
defer: (locals) => {
locals.setProps({color: 'red'});
locals.dispatch({ type: 'CLICKED_ASYNC' });
},
})
export default class About extends Component {
Expand Down
4 changes: 3 additions & 1 deletion examples/complex/src/components/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ function mapDispatchToProps(dispatch) {
}

// fetch triggers on both server and client
@provideHooks({ fetch: prefetchRepos })
@provideHooks({
fetch: prefetchRepos
})
// mergeReposProps enriches dispatch props with reposForceFetch
@connect(mapStateToProps, mapDispatchToProps, mergeReposProps)
export default class Main extends React.Component {
Expand Down
12 changes: 12 additions & 0 deletions examples/complex/src/sagas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { takeEvery } from 'redux-saga'
import { put, call } from 'redux-saga/effects'
import { delay } from 'redux-saga'

export function* incrementAsync() {
yield call(delay, 1000)
yield put({type: 'CLICKED'})
}

export default function* rootSaga() {
yield* takeEvery('CLICKED_ASYNC', incrementAsync)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default {
useDefaultReducers: true,
middlewares: 'src/redux/middlewares.js',
useDefaultMiddlewares: true,
sagas: 'src/redux/sagas.js',
},

// Will be moved to redux above eventually, now kept here to make the template upgradable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export default {
' documentation for what middlewares that are included.',
validator: required(isBoolean),
},
sagas: {
description: 'The Redux Saga to use as the root saga.',
validator: notEmpty(isPath),
},
},
clientLoading: {
description: 'The React component to use on the first client load while fetching data, will only ' +
Expand Down
12 changes: 12 additions & 0 deletions extensions/roc-package-web-app-react-dev/src/webpack/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ export default ({
);
}

const hasSagas = !!(buildSettings.redux.sagas && fileExists(buildSettings.redux.sagas));
if (hasSagas) {
const sagas = getAbsolutePath(buildSettings.redux.sagas);

newWebpackConfig.plugins.push(
new webpack.DefinePlugin({
REDUX_SAGAS: JSON.stringify(sagas),
})
);
}

const hasClientLoading = !!(buildSettings.clientLoading && fileExists(buildSettings.clientLoading));
if (hasClientLoading) {
const clientLoading = getAbsolutePath(buildSettings.clientLoading);
Expand Down Expand Up @@ -77,6 +88,7 @@ export default ({

HAS_REDUX_REDUCERS: hasReducers,
HAS_REDUX_MIDDLEWARES: hasMiddlewares,
HAS_REDUX_SAGA: hasSagas,
HAS_CLIENT_LOADING: hasClientLoading,
HAS_TEMPLATE_VALUES: hasTemplateValues,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* global __DEV__, HAS_CLIENT_LOADING, ROC_CLIENT_LOADING, ROC_PATH, HAS_REDUX_REDUCERS, document, window */
/* global __DEV__, HAS_CLIENT_LOADING, ROC_CLIENT_LOADING, ROC_PATH, HAS_REDUX_REDUCERS, document, window,
HAS_REDUX_SAGA, REDUX_SAGAS */
/* eslint-disable global-require */
import React from 'react';
import ReactDOM from 'react-dom';
Expand Down Expand Up @@ -98,6 +99,11 @@ export default function createClient({ createRoutes, createStore, mountNode }) {
const { syncHistoryWithStore } = require('react-router-redux');

const store = createStore(history, window.FLUX_STATE);

if (HAS_REDUX_SAGA) {
store.runSaga(require(REDUX_SAGAS).default);
}

history = syncHistoryWithStore(history, store, {
// We do not want to use adjustUrlOnReplay if the browser does
// not support the history API with pushState since this can lead
Expand Down
9 changes: 8 additions & 1 deletion extensions/roc-package-web-app-react/app/server/useReact.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global __DIST__, __DEV__ HAS_TEMPLATE_VALUES, TEMPLATE_VALUES, ROC_PATH */
/* global __DIST__, __DEV__ HAS_TEMPLATE_VALUES, TEMPLATE_VALUES, ROC_PATH, HAS_REDUX_SAGA, REDUX_SAGAS */

import useReactLib from 'roc-package-web-app-react/lib/app/server/useReact';

Expand All @@ -7,12 +7,19 @@ import Header from '../shared/header';
export default function useReact(createServer) {
// eslint-disable-next-line
const templateValues = HAS_TEMPLATE_VALUES ? require(TEMPLATE_VALUES) : undefined;
let reduxSagas;

if (HAS_REDUX_SAGA) {
reduxSagas = require(REDUX_SAGAS).default; // eslint-disable-line
}

return useReactLib(createServer, {
dev: __DEV__,
dist: __DIST__,
hasTemplateValues: HAS_TEMPLATE_VALUES,
templateValues,
rocPath: ROC_PATH,
Header,
reduxSagas,
});
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* globals __DEV__, __WEB__, window */
/* globals __DEV__, __WEB__, window, HAS_REDUX_SAGA */

import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import { routerMiddleware, routerReducer } from 'react-router-redux';
Expand All @@ -20,6 +20,14 @@ export default function createReduxStore(reducers, ...middlewares) {
(history, initialState) => {
let finalCreateStore;
const normalMiddlewares = [].concat(middlewares);
let sagaMiddleware;

// redux-saga
if (HAS_REDUX_SAGA) {
const createSagaMiddleware = require('redux-saga').default; // eslint-disable-line
sagaMiddleware = createSagaMiddleware();
normalMiddlewares.push(sagaMiddleware);
}

// Add the react-router-redux middleware
normalMiddlewares.push(routerMiddleware(history));
Expand Down Expand Up @@ -68,6 +76,10 @@ export default function createReduxStore(reducers, ...middlewares) {
});
}

if (sagaMiddleware) {
store.runSaga = sagaMiddleware.run;
}

return store;
};
}
1 change: 1 addition & 0 deletions extensions/roc-package-web-app-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"react-server-status": "~1.0.0",
"redial": "~0.4.1",
"redux": "~3.4.0",
"redux-saga": "0.12.0",
"redux-thunk": "~2.1.0",
"roc": "^1.0.0-rc.12",
"roc-package-web-app": "^1.0.0-beta.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export function reactRender({
staticRender = false,
hasTemplateValues,
templateValues,
reduxSagas,
}) {
return new Promise((resolve) => {
match({ history, routes: createRoutes(store), location: url },
Expand Down Expand Up @@ -109,10 +110,21 @@ export function reactRender({

const hooks = rocConfig.runtime.fetch.server;

let sagaPromise;
if (reduxSagas) {
sagaPromise = store.runSaga(reduxSagas).done;
}

return triggerHooks({
renderProps,
hooks,
locals,
}).then((result) => {
if (sagaPromise) {
store.dispatch(require('redux-saga').END); // eslint-disable-line
return sagaPromise.then(() => result);
}
return result;
}).then(({ redialMap, redialProps }) => {
let component = <RedialContext {...renderProps} redialMap={redialMap} />;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default function reactRouter({
templateValues,
rocPath,
Header,
reduxSagas,
}) {
const rocConfig = getSettings();

Expand Down Expand Up @@ -70,6 +71,7 @@ export default function reactRouter({
koaState: this.state,
hasTemplateValues,
templateValues,
reduxSagas,
});

if (redirect) {
Expand Down
2 changes: 1 addition & 1 deletion extensions/roc-package-web-app-react/src/roc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default {
'react-router-redux',
'react-server-status',
'redial',

'redux-saga',
'react-router-redial',
'redux',
'redux-thunk',
Expand Down

0 comments on commit 86b481b

Please sign in to comment.