1
1
import React from "react" ;
2
- import ReactAsync from "react-async" ;
3
2
import InlineCss from "react-inline-css" ;
4
- import Superagent from "superagent" ;
3
+ import Transmit from "react-transmit" ;
4
+ import __fetch from "isomorphic-fetch" ;
5
5
6
6
/**
7
7
* Main React application entry-point for both the server and client.
8
8
*
9
9
* @class Main
10
10
*/
11
11
const Main = React . createClass ( {
12
- mixins : [
13
- ReactAsync . Mixin
14
- ] ,
15
12
/**
16
13
* Server and client.
17
14
*/
18
- getInitialStateAsync ( completedFn ) {
15
+ componentWillMount ( ) {
19
16
/**
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
+ } ) ;
24
25
}
25
26
} ,
26
27
/**
27
- * Server and client .
28
+ * Client only .
28
29
*/
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
36
39
} ) ;
37
40
}
38
41
} ,
39
42
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
- } ,
64
43
/**
65
44
* <InlineCss> component allows you to write basic CSS for your component. Target
66
45
* your component with `&` and its children with `& selectors`. Be specific.
@@ -96,6 +75,11 @@ const Main = React.createClass({
96
75
const avatarSize = 32 ;
97
76
const avatarUrl = ( id ) => `https://avatars.githubusercontent.com/u/${ id } ?v=3&s=${ avatarSize } ` ;
98
77
78
+ /**
79
+ * This is a Transmit prop. See end of file.
80
+ */
81
+ const stargazers = this . props . stargazers ;
82
+
99
83
return (
100
84
< InlineCss stylesheet = { Main . css ( avatarSize ) } namespace = "Main" >
101
85
< a className = "github" href = { repositoryUrl } >
@@ -112,7 +96,7 @@ const Main = React.createClass({
112
96
< li > React.js + Router on the client and server</ li >
113
97
< li > React Hot Loader for instant client updates</ li >
114
98
< 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 >
116
100
< li > InlineCss-component for styling components</ li >
117
101
< li > Accessibility hints from react-a11y</ li >
118
102
</ ul >
@@ -123,7 +107,7 @@ const Main = React.createClass({
123
107
< h3 > Community</ h3 >
124
108
< p >
125
109
< a href = { repositoryUrl } title = "you here? star us!" >
126
- { this . state . stargazers . map ( ( user ) => {
110
+ { stargazers . map ( ( user ) => {
127
111
return < img key = { user . id } className = "avatar" src = { avatarUrl ( user . id ) } title = { user . login } alt = { user . login } /> ;
128
112
} ) }
129
113
< img className = "avatar" src = { avatarUrl ( 0 ) } alt = "you?" />
@@ -134,4 +118,37 @@ const Main = React.createClass({
134
118
}
135
119
} ) ;
136
120
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