Skip to content

Instantly share code, notes, and snippets.

@einarlove
Last active June 15, 2016 13:05
Show Gist options
  • Select an option

  • Save einarlove/ae8245f3bf71a433f0f9e015484452cc to your computer and use it in GitHub Desktop.

Select an option

Save einarlove/ae8245f3bf71a433f0f9e015484452cc to your computer and use it in GitHub Desktop.
import React from 'react'
const Component = ({ data, loading }) => (
<div>
{loading && <div>Loading data</div>}
{data && <div>{data}</div>}
</div>
)
const fetchData = ({ fetchAction, shouldFetch, selector }) => Component => {
class FetchData extends React.Component {
componentWillMount() {
fetchIfNeeded(nextProps)
}
componentWillReceiveProps(nextProps) {
fetchIfNeeded(nextProps)
}
fetchIfNeeded(_props) {
const state = this.getState()
const props = _props || this.props
if (shouldFetch(state, props)) {
this.props.dispatch(fetchAction(state, props))
}
}
getState() {
return this.context.store.getState()
}
render() {
const newProps = selector(this.getState(), this.props)
return <Component {...this.props} {...newProps} />
}
}
return connect()(FetchData)
}
const fetchFlightAction = dispatch => flightId => {
dispatch({ type: 'FETCH_FLIGHT', id: flightId })
return request(`/flight/${flightId}`)
.then(result => {
dispatch({
type: 'FETCH_FLIGHT_COMPLETE',
flight: result,
})
})
.catch(error => {
dispatch({
type: 'FETCH_FLIGHT_FAILED'
error: error,
})
})
}
const flightSelector = (state, flightId) => state.flights.flightsById[flightId]
const flightRquestSelector = (state, flightId) => {
const reuqest = state.flights.flightRequests[flightId]
if (reuqest) {
return {
...request,
data: flightSelector(flightId),
}
}
}
const shouldFetchFlightSelector = (state, flightId) => {
const request = flightRquestSelector(flightId)
if (!request) return true
const isStale = request.completedAt < subSeconds(new Date(), 30)
return isStale && request.loading && !flightSelector(flightId)
}
export default fetchData({
fetchAction: (state, ownProps) => fetchFlightAction(ownProps.flightId),
shouldFetch: (state, ownProps) => shouldFetchFlightSelector(state, ownProps.flightId),
selector: (state, ownProps) => flightRquestSelector(state, ownProps.flightId),
})(Component)
import React from 'react'
import { Link } from 'react-router'
import { cashay as cashayClient } from '../client'
import { connect } from 'react-redux'
const FlightDetail = ({ request }) => {
const { data, isComplete } = request
if (!isComplete) {
return <div>Loading</div>
}
return (
<div>
<h3>{data.flight.id}</h3>
<dl>
<dt>Status:</dt>
<dd>{data.flight.flightStatus}</dd>
<dt>From:</dt>
<dd>{data.flight.departure.airportName}</dd>
<Link to={`/flights/${data.flight.id}/test`}>{data.flight.id}</Link>
</dl>
</div>
)
}
FlightDetail.propTypes = {
request: React.PropTypes.object.isRequired,
}
const flightQuery = `
query (
$id: ID
) {
flight(id: $id) {
flightStatus
departure {
id
airportName
}
}
}
`
{
weatherRequest: {
},
// v0
flightRequestVerbose: {
action: ownProps => shouldFetchFlight(…) && fetchFlightById(…),
selector: ownProps => getFlightRequestById(…),
shouldFetch: true,
}
// v1
flightRequest: {
action: ownProps => fetchFlightById(…),
selector: ownProps => getFlightRequestById(…),
shouldFetch: ownProps, … => shouldFetchFlight(…),
},
}
if (shouldFetch(ownProps)) {
action(ownProps)
}
component.queries.flightRequest.action
const mapStateToProps = (state, { params }) => ({
request: getFlightRequestById(state, { id: params.id }, { ttl: '5 minutes' }),
// request: cashayClient.query(flightQuery, {
// component: 'FlightDetail',
// variables: {
// id: params.id,
// },
// }),
})
export default connect(mapStateToProps)(FlightDetail)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment