Skip to content

Commit f06291c

Browse files
committed
Server rendering for Apollo.
1 parent 877f434 commit f06291c

File tree

5 files changed

+204
-158
lines changed

5 files changed

+204
-158
lines changed

Diff for: lib/combineReducerWithApollo.js

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
"use strict";
22

33
const combineReducerWithApollo = (reducer, client, key = "apollo") => {
4-
const apolloReducer = client.reducer();
4+
const apolloReducer = client.reducer();
55

6-
return function combination(state = {}, action) {
7-
// Remove appolo key to prevent unexpected key warning.
8-
const apolloState = state[key];
9-
delete state[key];
6+
return function combination (state = {}, action) {
7+
// Remove appolo key to prevent unexpected key warning.
8+
const apolloState = state[key];
9+
delete state[key];
1010

11-
const nextState = reducer(state, action);
11+
const nextState = reducer(state, action);
1212

13-
const previousStateForApollo = apolloState;
14-
const nextStateForApollo = apolloReducer(previousStateForApollo, action);
13+
const previousStateForApollo = apolloState;
14+
const nextStateForApollo = apolloReducer(previousStateForApollo, action);
1515

16-
if (previousStateForApollo !== nextStateForApollo) {
17-
return Object.assign({}, nextState, {[key]: nextStateForApollo});
18-
} else {
19-
nextState[key] = previousStateForApollo;
20-
return nextState;
21-
}
22-
};
16+
if (previousStateForApollo !== nextStateForApollo) {
17+
return Object.assign({}, nextState, {[key]: nextStateForApollo});
18+
} else {
19+
nextState[key] = previousStateForApollo;
20+
return nextState;
21+
}
22+
};
2323
};
2424

2525
module.exports = combineReducerWithApollo;

Diff for: lib/renderToString.js

+30-22
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use strict";
22

3+
require("isomorphic-fetch");
34
const assert = require("assert");
45
const optionalRequire = require("optional-require")(require);
56
const React = optionalRequire("react");
@@ -9,31 +10,38 @@ const ReactRouter = require("react-router");
910
const Provider = require("react-redux").Provider;
1011

1112
const renderToString = (req, store, match, withIds) => { // eslint-disable-line
12-
if (req.app && req.app.disableSSR) {
13-
return "";
14-
} else {
15-
assert(React, "Can't do SSR because React module is not available");
16-
assert(ReactDomServer, "Can't do SSR because ReactDomServer module is not available");
13+
if (req.app && req.app.disableSSR) {
14+
return "";
15+
} else {
16+
assert(React, "Can\'t do SSR because React module is not available");
17+
assert(ReactDomServer,
18+
"Can\'t do SSR because ReactDomServer module is not available");
1719

18-
const app = req.server && req.server.app || req.app;
19-
if (app.apollo) {
20-
assert(ReactApollo, "Can't use Apollo because ReactApollo module is not available");
20+
const app = req.server && req.server.app || req.app;
21+
if (app.apollo) {
22+
assert(ReactApollo,
23+
"Can\'t use Apollo because ReactApollo module is not available");
2124

22-
return (withIds ? ReactDomServer.renderToString : ReactDomServer.renderToStaticMarkup)(
23-
React.createElement(
24-
ReactApollo.ApolloProvider, { store, client: app.apollo },
25-
React.createElement(ReactRouter.RouterContext, match.renderProps)
26-
)
27-
);
28-
} else {
29-
return (withIds ? ReactDomServer.renderToString : ReactDomServer.renderToStaticMarkup)(
30-
React.createElement(
31-
Provider, { store },
32-
React.createElement(ReactRouter.RouterContext, match.renderProps)
33-
)
34-
);
35-
}
25+
const element = React.createElement(
26+
ReactApollo.ApolloProvider, {store, client: app.apollo},
27+
React.createElement(ReactRouter.RouterContext, match.renderProps)
28+
);
29+
return ReactApollo.getDataFromTree(element).then(() => {
30+
return (withIds
31+
? ReactDomServer.renderToString
32+
: ReactDomServer.renderToStaticMarkup)(element);
33+
});
34+
} else {
35+
return (withIds
36+
? ReactDomServer.renderToString
37+
: ReactDomServer.renderToStaticMarkup)(
38+
React.createElement(
39+
Provider, {store},
40+
React.createElement(ReactRouter.RouterContext, match.renderProps)
41+
)
42+
);
3643
}
44+
}
3745
};
3846

3947
module.exports = renderToString;

Diff for: package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "electrode-apollo-redux-engine",
3-
"version": "1.0.3",
3+
"version": "1.0.4",
44
"description": "Integrating Electrode with Apollo and Redux",
55
"main": "index.js",
66
"scripts": {
@@ -35,6 +35,7 @@
3535
"redux": "^3.7.2"
3636
},
3737
"dependencies": {
38+
"isomorphic-fetch": "^2.2.1",
3839
"optional-require": "^1.0.0",
3940
"react-redux": "^5.0.5",
4041
"react-router": "^3.0.5"

Diff for: test/spec/combine.spec.js

+51-43
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,69 @@
22

33
const createStore = require("redux").createStore;
44
const combineReducers = require("redux").combineReducers;
5+
const applyMiddleware = require("redux").applyMiddleware;
6+
const compose = require("redux").compose;
57
const ApolloClient = require("react-apollo").ApolloClient;
68

79
const {combineReducerWithApollo} = require("../..");
810

911
const checkBox = (store, action) => {
10-
if (action.type === "TOGGLE_CHECK") {
11-
return {
12-
checked: !store.checked
13-
};
14-
}
12+
if (action.type === "TOGGLE_CHECK") {
13+
return {
14+
checked: !store.checked
15+
};
16+
}
1517

16-
return store || {checked: false};
18+
return store || {checked: false};
1719
};
1820

1921
const number = (store, action) => {
20-
if (action.type === "INC_NUMBER") {
21-
return {
22-
value: store.value + 1
23-
};
24-
} else if (action.type === "DEC_NUMBER") {
25-
return {
26-
value: store.value - 1
27-
};
28-
}
29-
30-
return store || {value: 0};
22+
if (action.type === "INC_NUMBER") {
23+
return {
24+
value: store.value + 1
25+
};
26+
} else if (action.type === "DEC_NUMBER") {
27+
return {
28+
value: store.value - 1
29+
};
30+
}
31+
32+
return store || {value: 0};
3133
};
3234

3335
describe("Combine reducer with Apollo", function () {
3436

35-
it("should combine existing root reducer", () => {
36-
const client = new ApolloClient();
37-
38-
const rootReducer = combineReducers({
39-
checkBox,
40-
number
41-
});
42-
43-
const initialState = {
44-
checkBox: {checked: false},
45-
number: {value: 999}
46-
};
47-
const store = createStore(combineReducerWithApollo(rootReducer, client), initialState);
48-
expect(store.getState()).to.have.all.keys("checkBox", "number", "apollo");
49-
expect(store.getState().checkBox).to.deep.equal({checked: false});
50-
expect(store.getState().number).to.deep.equal({value: 999});
51-
52-
store.dispatch({type: "TOGGLE_CHECK"});
53-
expect(store.getState().checkBox).to.deep.equal({checked: true});
54-
store.dispatch({type: "TOGGLE_CHECK"});
55-
expect(store.getState().checkBox).to.deep.equal({checked: false});
56-
57-
store.dispatch({type: "INC_NUMBER"});
58-
expect(store.getState().number).to.deep.equal({value: 1000});
59-
store.dispatch({type: "DEC_NUMBER"});
60-
expect(store.getState().number).to.deep.equal({value: 999});
37+
it("should combine existing root reducer", () => {
38+
const client = new ApolloClient();
39+
40+
const rootReducer = combineReducers({
41+
checkBox,
42+
number
6143
});
44+
45+
const initialState = {
46+
checkBox: {checked: false},
47+
number: {value: 999}
48+
};
49+
const store = createStore(
50+
combineReducerWithApollo(rootReducer, client),
51+
initialState,
52+
compose(
53+
applyMiddleware(client.middleware())
54+
)
55+
);
56+
expect(store.getState()).to.have.all.keys("checkBox", "number", "apollo");
57+
expect(store.getState().checkBox).to.deep.equal({checked: false});
58+
expect(store.getState().number).to.deep.equal({value: 999});
59+
60+
store.dispatch({type: "TOGGLE_CHECK"});
61+
expect(store.getState().checkBox).to.deep.equal({checked: true});
62+
store.dispatch({type: "TOGGLE_CHECK"});
63+
expect(store.getState().checkBox).to.deep.equal({checked: false});
64+
65+
store.dispatch({type: "INC_NUMBER"});
66+
expect(store.getState().number).to.deep.equal({value: 1000});
67+
store.dispatch({type: "DEC_NUMBER"});
68+
expect(store.getState().number).to.deep.equal({value: 999});
69+
});
6270
});

0 commit comments

Comments
 (0)