At this point, you have the GraphQL backend up and running. Now, you can focus on your React components in the frontend. In particular, you're going to look at Relay in a React Native context, which really only has minor differences. For example, in web apps, it's usually react-router that bootstraps Relay. In React Native, it's a little different. Let's look at the App.js file that serves as the entry point for your native app:
import React from 'react';
import { View, Text } from 'react-native';
import { Network } from 'relay-local-schema';
import { Environment, RecordSource, Store } from 'relay-runtime';
import { QueryRenderer, graphql } from 'react-relay';
import schema from './data/schema';
import styles from './styles';
import TodoInput from './TodoInput';
import TodoList from './TodoList';
if (typeof Buffer === 'undefined')
global.Buffer = require('buffer').Buffer;
const environment = new Environment({
network: Network.create({ schema }),
store: new Store(new RecordSource())
});
export default () => (
<QueryRenderer
environment={environment}
query={graphql`
query App_Query($status: String!) {
viewer {
...TodoList_viewer
}
}
`}
variables={{ status: 'any' }}
render={({ error, props }) => {
if (error) {
return <Text>Error!</Text>;
}
if (!props) {
return <Text>Loading...</Text>;
}
return (
<View style={styles.container}>
<TodoInput environment={environment} {...props} />
<TodoList {...props} />
</View>
);
}}
/>
);
Let's break down what's happening here, starting with the environment constant:
const environment = new Environment({
network: Network.create({ schema }),
store: new Store(new RecordSource())
});
This is how you communicate with the GraphQL backend, by configuring a network. In this example, you're importing Network from relay-local-schema, which means that no network requests are being made. This is really handy for when you're getting started—especially building a React Native app.
Next, there's the QueryRenderer component. This Relay component is used to render other components that depend on GraphQL queries. It expects a query property:
query={graphql`
query App_Query($status: String!) {
viewer {
...TodoList_viewer
}
}
`}
Note that queries are prefixed by the module that they're in. In this case, App. This query uses a GraphQL fragment from another module, TodoList, and is named TodoList_viewer. You can pass variables to the query:
variables={{ status: 'any' }}
Then, the render property is a function that renders your components when the GraphQL data is ready:
render={({ error, props }) => {
if (error) {
return <Text>Error!</Text>;
}
if (!props) {
return <Text>Loading...</Text>;
}
return (
<View style={styles.container}>
<TodoInput environment={environment} {...props} />
<TodoList {...props} />
</View>
);
}}
If something went wrong, error will contain information about the error. If there's no error and no props, it's safe to assume that the GraphQL data is still loading.