11import React from "react" ;
2- import ReactAsync from "react-async" ;
32import 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 */
1111const 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