Skip to content
This repository was archived by the owner on Jan 11, 2019. It is now read-only.

Commit e513d33

Browse files
committed
Use React Transmit (Relay library) to replace react-async and remove fibers dependency.
1 parent 1bbc3f2 commit e513d33

File tree

5 files changed

+84
-70
lines changed

5 files changed

+84
-70
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Isomorphic starterkit with server-side React rendering using
1212
[react.js](https://facebook.github.io/react),
1313
[react-router](https://github.com/rackt/react-router),
1414
[react-hot-loader](https://gaearon.github.io/react-hot-loader),
15-
[react-async](https://github.com/andreypopp/react-async),
16-
[react-a11y](https://github.com/rackt/react-a11y),
17-
[react-inline-css](https://github.com/RickWong/react-inline-css)
15+
[react-transmit](https://github.com/RickWong/react-transmit),
16+
[react-inline-css](https://github.com/RickWong/react-inline-css),
17+
[react-a11y](https://github.com/rackt/react-a11y)
1818

1919
## Features
2020

@@ -24,7 +24,7 @@ Isomorphic starterkit with server-side React rendering using
2424
- React.js + Router on the client and server
2525
- React Hot Loader for instant client updates
2626
- Babel.js automatically compiles ES6 + ES7
27-
- React-async to preload on server to client
27+
- React Transmit to preload on server to client
2828
- InlineCss-component for styling components
2929
- Accessibility hints from react-a11y
3030

@@ -39,8 +39,9 @@ It just works out-of-the-box.
3939
npm install
4040
npm run watch # yes, one command for server and client development!
4141

42-
# production
43-
NODE_ENV=production npm run build
42+
# production build and run
43+
NODE_ENV=production npm run build
44+
NODE_ENV=production npm run browser
4445

4546
## Usage
4647

package.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-isomorphic-starterkit",
33
"description": "Isomorphic starterkit with server-side React rendering.",
4-
"version": "1.5.2",
4+
"version": "2.0.0",
55
"license": "BSD-3",
66
"repository": {
77
"type": "git",
@@ -28,23 +28,22 @@
2828
},
2929
"dependencies": {
3030
"babel": "4.7.16",
31-
"fibers": "1.0.5",
3231
"hapi": "8.4.0",
3332
"piping": "0.1.7",
3433
"react": "0.12.2",
3534
"react-a11y": "0.0.6",
36-
"react-async": "2.1.0",
3735
"react-inline-css": "1.1.1",
3836
"react-router": "0.12.4",
39-
"superagent": "1.1.0"
37+
"react-transmit": "2.0.0",
38+
"isomorphic-fetch": "2.0.0"
4039
},
4140
"devDependencies": {
4241
"babel-core": "4.7.16",
4342
"babel-loader": "4.2.0",
4443
"babel-runtime": "4.7.16",
4544
"concurrently": "0.0.5",
4645
"json-loader": "0.5.1",
47-
"react-hot-loader": "1.2.3",
46+
"react-hot-loader": "1.2.4",
4847
"webpack": "1.7.3",
4948
"webpack-dev-server": "1.7.0"
5049
},

src/client.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
2-
import ReactAsync from "react-async";
32
import Router from "react-router";
3+
import Transmit from "react-transmit";
44
import routes from "views/Routes";
55

66
/**
@@ -14,7 +14,7 @@ if (process.env.NODE_ENV !== "production") {
1414
* Fire-up React Router.
1515
*/
1616
Router.run(routes, Router.HistoryLocation, (Handler) => {
17-
React.render(<Handler />, document.getElementById("react-root"));
17+
Transmit.render(Handler, {}, document.getElementById("react-root"));
1818
});
1919

2020
/**

src/server.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {Server} from "hapi";
22
import React from "react";
3-
import ReactAsync from "react-async";
43
import Router from "react-router";
4+
import Transmit from "react-transmit";
55
import routes from "views/Routes";
66

77
/**
@@ -31,11 +31,9 @@ server.ext("onPreResponse", (request, reply) => {
3131
}
3232

3333
Router.run(routes, request.path, (Handler, router) => {
34-
ReactAsync.renderToStringAsync(
35-
<Handler />,
36-
(error, reactString, reactData) => {
37-
let output = (
38-
`<!doctype html>
34+
Transmit.renderToString(Handler, {}, (reactString, reactData) => {
35+
let output = (
36+
`<!doctype html>
3937
<html lang="en-us">
4038
<head>
4139
<meta charset="utf-8">
@@ -46,13 +44,12 @@ server.ext("onPreResponse", (request, reply) => {
4644
<div id="react-root">${reactString}</div>
4745
</body>
4846
</html>`
49-
);
47+
);
5048

51-
const webserver = process.env.NODE_ENV === "production" ? "" : "//localhost:8080";
52-
output = ReactAsync.injectIntoMarkup(output, reactData, [`${webserver}/dist/client.js`]);
49+
const webserver = process.env.NODE_ENV === "production" ? "" : "//localhost:8080";
50+
output = Transmit.injectIntoMarkup(output, reactData, [`${webserver}/dist/client.js`]);
5351

54-
reply(output);
55-
}
56-
);
52+
reply(output);
53+
});
5754
})
5855
});

src/views/Main.js

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,45 @@
11
import React from "react";
2-
import ReactAsync from "react-async";
32
import InlineCss from "react-inline-css";
4-
import Superagent from "superagent";
3+
import Transmit from "react-transmit";
4+
import __fetch from "isomorphic-fetch";
55

66
/**
77
* Main React application entry-point for both the server and client.
88
*
99
* @class Main
1010
*/
1111
const Main = React.createClass({
12-
mixins: [
13-
ReactAsync.Mixin
14-
],
1512
/**
1613
* Server and client.
1714
*/
18-
getInitialStateAsync (completedFn) {
15+
componentWillMount () {
1916
/**
20-
* Load the first 100 stargazers on the server.
21-
*/
22-
if (__SERVER__) {
23-
Main.loadStargazersFn([], false, 1, completedFn);
17+
* Load the next 100 stargazers.
18+
*/
19+
if (__CLIENT__) {
20+
this.props.setQueryParams({
21+
prevStargazers: this.props.stargazers,
22+
nextPage: this.props.queryParams.nextPage + 1,
23+
pagesToFetch: this.props.queryParams.pagesToFetch - 1
24+
});
2425
}
2526
},
2627
/**
27-
* Server and client.
28+
* Client only.
2829
*/
29-
componentWillMount() {
30-
if (__CLIENT__) {
31-
/**
32-
* Load the rest of the stargazers on the client.
33-
*/
34-
Main.loadStargazersFn(this.state.stargazers || [], true, 2, (error, state) => {
35-
this.setState(state);
30+
componentWillReceiveProps (nextProps) {
31+
/**
32+
* Load the rest of the stargazers repeatedly.
33+
*/
34+
if (nextProps.queryParams.pagesToFetch > 0) {
35+
this.props.setQueryParams({
36+
prevStargazers: nextProps.stargazers,
37+
nextPage: nextProps.queryParams.nextPage + 1,
38+
pagesToFetch: nextProps.queryParams.pagesToFetch - 1
3639
});
3740
}
3841
},
3942
statics: {
40-
/**
41-
* Use Superagent to retrieve the list of GitHub stargazers.
42-
*/
43-
loadStargazersFn (stargazers, untilAllLoaded, currentPage, completedFn) {
44-
Superagent.get(
45-
`https://api.github.com/repos/RickWong/react-isomorphic-starterkit/stargazers?per_page=100&page=${currentPage}`
46-
).
47-
end((error, response) => {
48-
if (response && Array.isArray(response.body)) {
49-
stargazers = stargazers.concat(response.body.map((user) => {
50-
return {
51-
id: user.id,
52-
login: user.login
53-
};
54-
}));
55-
56-
if (untilAllLoaded && response.body.length >= 100) {
57-
return Main.loadStargazersFn(stargazers, untilAllLoaded, currentPage + 1, completedFn);
58-
}
59-
}
60-
61-
completedFn(error, {stargazers});
62-
});
63-
},
6443
/**
6544
* <InlineCss> component allows you to write basic CSS for your component. Target
6645
* your component with `&` and its children with `& selectors`. Be specific.
@@ -96,6 +75,11 @@ const Main = React.createClass({
9675
const avatarSize = 32;
9776
const avatarUrl = (id) => `https://avatars.githubusercontent.com/u/${id}?v=3&s=${avatarSize}`;
9877

78+
/**
79+
* This is a Transmit prop. See end of file.
80+
*/
81+
const stargazers = this.props.stargazers;
82+
9983
return (
10084
<InlineCss stylesheet={Main.css(avatarSize)} namespace="Main">
10185
<a className="github" href={repositoryUrl}>
@@ -112,7 +96,7 @@ const Main = React.createClass({
11296
<li>React.js + Router on the client and server</li>
11397
<li>React Hot Loader for instant client updates</li>
11498
<li>Babel.js automatically compiles ES6 + ES7</li>
115-
<li>React-async to preload on server to client</li>
99+
<li>React Transmit to preload on server to client</li>
116100
<li>InlineCss-component for styling components</li>
117101
<li>Accessibility hints from react-a11y</li>
118102
</ul>
@@ -123,7 +107,7 @@ const Main = React.createClass({
123107
<h3>Community</h3>
124108
<p>
125109
<a href={repositoryUrl} title="you here? star us!">
126-
{this.state.stargazers.map((user) => {
110+
{stargazers.map((user) => {
127111
return <img key={user.id} className="avatar" src={avatarUrl(user.id)} title={user.login} alt={user.login} />;
128112
})}
129113
<img className="avatar" src={avatarUrl(0)} alt="you?" />
@@ -134,4 +118,37 @@ const Main = React.createClass({
134118
}
135119
});
136120

137-
export default Main;
121+
/**
122+
* Use React Transmit to write declarative queries as Promises.
123+
*/
124+
export default Transmit.createContainer(Main, {
125+
queryParams: {
126+
prevStargazers: [],
127+
nextPage: 1,
128+
pagesToFetch: 22
129+
},
130+
queries: {
131+
stargazers (queryParams) {
132+
/**
133+
* Return a Promise of all the stargazers.
134+
*/
135+
return fetch(
136+
`https://api.github.com/repos/RickWong/react-isomorphic-starterkit/stargazers?per_page=100&page=${queryParams.nextPage}`
137+
).then((response) => {
138+
return response.json();
139+
}).then((page) => {
140+
if (!page || !page.length) {
141+
queryParams.pagesToFetch = 0;
142+
return queryParams.prevStargazers;
143+
}
144+
145+
const stargazers = page.map((user) => ({
146+
id: user.id,
147+
login: user.login
148+
}));
149+
150+
return queryParams.prevStargazers.concat(stargazers);
151+
});
152+
}
153+
}
154+
});

0 commit comments

Comments
 (0)