RelayUtils.js
October 3, 2016 ยท View on GitHub
// @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
// TODO: Make proper loading / failure components.
const LoadingView = () => (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
const FailureView = ({ error, retry }) => (
<View style={{ paddingTop: 46, alignItems: 'center' }}>
export function createRenderer(
Component: ReactClass<>,
config: Config
): ReactClass<> {
return createRendererInternal(Component, {
forceFetch: true,
renderLoading: () =>
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; }