Skip to content

Commit

Permalink
Add support for helpers in redux-thunk actions (#650)
Browse files Browse the repository at this point in the history
Support for isomorphic `fetch` and `graphqlRequest`
helpers in redux-thunk action creators
  • Loading branch information
langpavel authored and koistya committed May 17, 2016
1 parent 4a73920 commit 2ea534e
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 23 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"react-dom": "15.0.1",
"react-redux": "^4.4.5",
"redux": "^3.4.0",
"redux-thunk": "^2.0.1",
"redux-thunk": "^2.1.0",
"sequelize": "^3.21.0",
"source-map-support": "0.4.0",
"sqlite3": "^3.1.3",
Expand Down
4 changes: 3 additions & 1 deletion src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ app.get('*', async (req, res, next) => {
data.trackingId = analytics.google.trackingId;
}

const store = configureStore({});
const store = configureStore({}, {
cookie: req.headers.cookie,
});

store.dispatch(setRuntimeVariable({
name: 'initialNow',
Expand Down
55 changes: 34 additions & 21 deletions src/store/configureStore.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';

const middleware = [thunk];

let enhancer;

if (__DEV__ && process.env.BROWSER) {
const createLogger = require('redux-logger');
const logger = createLogger({
collapsed: true,
});
middleware.push(logger);

enhancer = compose(
applyMiddleware(...middleware),
import createHelpers from './createHelpers';

export default function configureStore(initialState, helpersConfig) {
const helpers = createHelpers(helpersConfig);
const middleware = [thunk.withExtraArgument(helpers)];

let enhancer;

if (__DEV__) {
if (process.env.BROWSER) {
const createLogger = require('redux-logger');
middleware.push(createLogger({
collapsed: true,
}));
} else {
// Server side redux action logger
middleware.push(store => next => action => { // eslint-disable-line no-unused-vars
const payload = JSON.stringify(action.payload);
console.log(` * ${action.type}: ${payload}`); // eslint-disable-line no-console
return next(action);
});
}

// https://github.com/zalmoxisus/redux-devtools-extension#redux-devtools-extension
window.devToolsExtension ? window.devToolsExtension() : f => f,
);
} else {
enhancer = applyMiddleware(...middleware);
}
let devToolsExtension = f => f;
if (process.env.BROWSER && window.devToolsExtension) {
devToolsExtension = window.devToolsExtension();
}

enhancer = compose(
applyMiddleware(...middleware),
devToolsExtension,
);
} else {
enhancer = applyMiddleware(...middleware);
}

export default function configureStore(initialState) {
// Note: only Redux >= 3.1.0 supports passing enhancer as third argument.
// See https://github.com/rackt/redux/releases/tag/v3.1.0
const store = createStore(rootReducer, initialState, enhancer);

Expand Down
50 changes: 50 additions & 0 deletions src/store/createHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import fetch from '../core/fetch';

function createGraphqlRequest(fetchKnowingCookie) {
return async function graphqlRequest(query, variables) {
const fetchConfig = {
method: 'post',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ query, variables }),
credentials: 'include',
};
const resp = await fetchKnowingCookie('/graphql', fetchConfig);
if (resp.status !== 200) throw new Error(resp.statusText);
return await resp.json();
};
}

function createFetchKnowingCookie({ cookie }) {
if (!process.env.BROWSER) {
return (url, options = {}) => {
const isLocalUrl = /^\/($|[^\/])/.test(url);

// pass cookie only for itself.
// We can't know cookies for other sites BTW
if (isLocalUrl && options.credentials === 'include') {
const headers = {
...options.headers,
cookie,
};
return fetch(url, { ...options, headers });
}

return fetch(url, options);
};
}

return fetch;
}

export default function createHelpers(config) {
const fetchKnowingCookie = createFetchKnowingCookie(config);
const graphqlRequest = createGraphqlRequest(fetchKnowingCookie);

return {
fetch: fetchKnowingCookie,
graphqlRequest,
};
}

0 comments on commit 2ea534e

Please sign in to comment.