-
-
Save janicduplessis/f513032eb37cdde5d050d9ce8cf0b92a to your computer and use it in GitHub Desktop.
This file contains 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
// @flow | |
import React from 'react'; | |
import { | |
ActivityIndicator, | |
Text, | |
TouchableOpacity, | |
View, | |
} from 'react-native'; | |
import Relay from 'react-relay'; | |
type Variables = {[name: string]: mixed}; | |
type Config = { | |
queries: {[name: string]: any}; | |
queriesParams?: ?(props: Object) => Object; | |
fragments: {[name: string]: any}; | |
initialVariables?: Variables; | |
prepareVariables?: (prevVariables: Variables, route: any) => Variables; | |
forceFetch?: bool; | |
onReadyStateChange?: (readyState: any) => void; | |
renderFetched?: ( | |
props: Object, | |
fetchState: { done: bool; stale: bool } | |
) => ?ReactElement<any>; | |
renderLoading?: () => ?ReactElement<any>; | |
renderFailure?: (error: Error, retry: ?() => void) => ?ReactElement<any>; | |
}; | |
// TODO: Make proper loading / failure components. | |
const LoadingView = () => ( | |
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> | |
<ActivityIndicator size="large" /> | |
</View> | |
); | |
const FailureView = ({ error, retry }) => ( | |
<View style={{ paddingTop: 46, alignItems: 'center' }}> | |
<Text>Error</Text> | |
<Text>{error.message}</Text> | |
<TouchableOpacity onPress={retry}> | |
<Text>Try again</Text> | |
</TouchableOpacity> | |
</View> | |
); | |
export function createRenderer( | |
Component: ReactClass<*>, | |
config: Config | |
): ReactClass<*> { | |
return createRendererInternal(Component, { | |
forceFetch: true, | |
renderLoading: () => <LoadingView />, | |
renderFailure: (error, retry) => <FailureView error={error} retry={retry} />, | |
...config, | |
}); | |
} | |
function createRendererInternal( | |
Component: ReactClass<*>, | |
config: Config | |
): ReactClass<*> { | |
const { | |
queries, | |
queriesParams, | |
forceFetch, | |
renderFetched, | |
renderLoading, | |
renderFailure, | |
onReadyStateChange, | |
fragments, | |
initialVariables, | |
prepareVariables, | |
} = config; | |
const RelayComponent = Relay.createContainer(Component, { | |
fragments, | |
initialVariables, | |
prepareVariables, | |
}); | |
class RelayRendererWrapper extends React.Component { | |
state = { | |
queryConfig: this._computeQueryConfig(this.props), | |
}; | |
render() { | |
return ( | |
<Relay.Renderer | |
Container={RelayComponent} | |
forceFetch={forceFetch || false} | |
onReadyStateChange={onReadyStateChange} | |
queryConfig={this.state.queryConfig} | |
environment={Relay.Store} | |
render={({ done, error, props, retry, stale }) => { | |
if (error) { | |
if (renderFailure) { | |
return renderFailure(error, retry); | |
} | |
} else if (props) { | |
if (renderFetched) { | |
return renderFetched({ ...this.props, ...props }, { done, stale }); | |
} else { | |
return <RelayComponent {...this.props} {...props} />; | |
} | |
} else if (renderLoading) { | |
return renderLoading(); | |
} | |
return undefined; | |
}} | |
/> | |
); | |
} | |
componentWillReceiveProps(nextProps: Object) { | |
if (this.props.routeParams !== nextProps.routeParams) { | |
this.setState({ | |
queryConfig: this._computeQueryConfig(nextProps), | |
}); | |
} | |
} | |
_computeQueryConfig(props: Object) { | |
const params = queriesParams ? queriesParams(props) : {}; | |
const queryConfig = { | |
name: `relay-route-${RelayComponent.displayName}`, | |
queries: { ...queries }, | |
params, | |
}; | |
return queryConfig; | |
} | |
} | |
return RelayRendererWrapper; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You should avoid the use of dash here:
relay-route-${RelayComponent.displayName}
for the name of QueryConfigit should be
parenthesis ()
anddash -
can cause some problems in Graphqlfor instance:
take a look on this: r0b1n/rnrf-relay-renderer#10