Created
January 7, 2016 23:27
-
-
Save meisinger/dc363eecd5c207d46b81 to your computer and use it in GitHub Desktop.
example of react with a page view approach (no flux or events)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
import React from 'react'; | |
import ReactDom from 'react-dom'; | |
import { UserService, ExampleService } from './service'; | |
import Promise from 'bluebird'; | |
import assign from 'object-assign'; | |
class ComponentWrapper { | |
static ViewAggregate(Component, fetches) { | |
return class ViewAggregateComponent extends React.Component { | |
static load(params = {}, query = {}) { | |
return Promise.all( | |
fetches.map((fetch) => { | |
return fetch.resolve(params, query) | |
.then((resolved) => { | |
var data = {}; | |
data[fetch.label] = resolved; | |
return data; | |
}); | |
}) | |
); | |
} | |
constructor(props) { | |
super(props); | |
this.state = { loading: true }; | |
} | |
componentDidMount() { | |
ViewAggregateComponent.load(this.props.params, this.props.query) | |
.then((results) => { | |
var state = results.reduce((aggregate, item) => { | |
return assign(aggregate, item); | |
}, { loading: false }); | |
this.setState(state); | |
}); | |
} | |
render() { | |
if (this.state.loading) | |
return null; | |
return (<Component {...this.state} />); | |
} | |
}; | |
} | |
}; | |
class ProfileView extends React.Component { | |
constructor() { | |
super(); | |
} | |
render() { | |
return ( | |
<div> | |
<div>{'Hello from a Simple Profile'}</div> | |
<ProfileComponent {...this.props.profile} /> | |
<DateInfoComponent {...this.props.dateInfo} /> | |
</div> | |
); | |
} | |
}; | |
class ProfileComponent extends React.Component { | |
constructor() { | |
super(); | |
} | |
render() { | |
return ( | |
<div> | |
<div>{'First Name: ' + this.props.firstName}</div> | |
<div>{'Last Name: ' + this.props.lastName}</div> | |
</div> | |
); | |
} | |
}; | |
class DateInfoComponent extends React.Component { | |
constructor() { | |
super(); | |
} | |
render() { | |
return (<div>{'Token: ' + this.props.token}</div>); | |
} | |
}; | |
class ProfilePage extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
resolvers: [ | |
{label: 'profile', resolve: UserService.fetch}, | |
{label: 'dateInfo', resolve: ExampleService.fetch} | |
] | |
}; | |
} | |
render() { | |
var Container = ComponentWrapper.ViewAggregate(ProfileView, this.state.resolvers); | |
return (<Container {...this.props} />); | |
} | |
} | |
class Application extends React.Component { | |
constructor() { | |
super(); | |
this.state = { | |
statement: 'Goodbye from React!' | |
}; | |
} | |
render() { | |
var context = { | |
params: { id: 2 } | |
}; | |
return ( | |
<div> | |
<div>{this.props.statement}</div> | |
<ProfilePage {...context} /> | |
</div> | |
); | |
} | |
}; | |
document.addEventListener('DOMContentLoaded', (evt) => { | |
ReactDom.render( | |
<Application statement="Hello from React!" />, | |
document.getElementById('application_view') | |
); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
import Promise from 'bluebird'; | |
import assign from 'object-assign'; | |
import superagent from 'superagent'; | |
import moment from 'moment'; | |
let _userCollection = []; | |
export class ExampleService { | |
constructor() { | |
} | |
static fetch(params, query) { | |
return new Promise((resolve, reject) => { | |
superagent | |
.get('/api/date-info') | |
.set('Accept', 'application/json') | |
.end((error, response) => { | |
if (error) | |
reject(error); | |
else { | |
var data = response.body; | |
var model = assign({}, { | |
token: data.access_token, | |
refresh: data.refresh_token | |
}); | |
resolve(model); | |
} | |
}); | |
}); | |
} | |
}; | |
export class UserService { | |
constructor() { | |
} | |
static fetch(params, query) { | |
return new Promise((resolve, reject) => { | |
superagent | |
.get('/api/user/' + params.id || 1) | |
.set('Accept', 'application/json') | |
.end((error, response) => { | |
if (error) | |
reject(error); | |
else { | |
var model = UserStore.map(response.body); | |
resolve(model); | |
} | |
}); | |
}); | |
} | |
}; | |
export class UserStore { | |
static get(id) { | |
var result = _userCollection.filter((item) => { | |
return (item.id === id); | |
}); | |
if (result && result !== null && result.length !== 0) { | |
var model = result[0]; | |
var stale = moment().subtract(30, 'seconds'); | |
if (model.fetched.isAfter(stale)) | |
return model; | |
} | |
return undefined; | |
} | |
static store(model) { | |
var result = _userCollection.filter((item) => { | |
return (item.id === model.id); | |
}); | |
if (result && result !== null && result.length !== 0) { | |
var existing = result[0]; | |
var index = _userCollection.indexOf(existing); | |
_userCollection.splice(index, 1); | |
} | |
_userCollection.push(model); | |
} | |
static map(data) { | |
var model = assign({}, { | |
id: data.id, | |
firstName: data.firstName, | |
lastName: data.lastName, | |
fetched: moment() | |
}); | |
return model; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment