React Native with React Apollo

Here at Facebook Developer Circle Malang, we held React Native workshop using Expo.io and Lumen. Everyone (including me) are encouraged to create a mobile apps using React Native. And then I had an idea using some kind of RESTful API like swapi.co or pokeapi.co but with GraphQL. After hours of researching, I decided to use Starwars GraphQL server from GraphQL.org.

My stack will be looks like this:

- Expo
- React Navigation (for screen navigation)
- React Apollo (This awesome package has `graphql` and `gql` in it)

Quite simple, huh?! OK, let’s code!

Integrating Apollo Provider with React Navigation

First, define your route and add it to React Navigation’s StackNavigator. Example:

Second, in main entrypoint file (mine is `main.js`), import ApolloClient, ApolloProvider, createNetworkInterface from react-apollo module and initialize an ApolloClient.

And then, crate a class for wrapping your router with ApolloProvider and register it as your root component.

So the full code for the main entrypoint looks like this:

GraphQL Query on Component

If you’re not familiar with GraphQL query, you might want to read GraphQL Query documentation first. On this example, we just do a query to get a detail with an argument and variable from Starwars API.

With GraphQL, we can specify which field(s) do we need just like `SELECT` in SQL query. We just need `title`, `openingCrawl`, `director`, `producers`, and `releaseDate` fields for this example. With GraphQL, we can query like this

We just need to specify the object name (it’s `film` in this example), arguments (it’s `id: $id`), and fields (within curly braces). Please do note that we need to add either comma, new line or even space for each fields. Valid query example

You can pick your flavor. Personally, I like the one with new line. It’s much more readable if we deals with lots of fields later. Let’s go ahead.

Now we can wrap the object with a `query` statement

If you’re looking at the `query` statement, it has `$id` and `ID!` on its parameter (just like a normal function pattern). Basically, GraphQL has a type system which mean that we need to specify the type for each of its parameter.

So, we can say that `query` statement has a parameter called `$id` which has type of `ID` (GraphQL built-in type). And the exclamation mark (`ID!`) means that the field is non-nullable or required.

And if you’re looking at the `film` object, it also has a parameter called `id`. We can passing the arguments from `query` statement to the `film` object (just like normal function) just like the code above.

OK, so how do we get the `$id`? React-Apollo comes with a handy way how to get the variable(s). Please refer to this page. Basically, React-Apollo is just a High Order Component for React. The `graphql` container has a pattern like this

graphql(query, [config])(component)

As you can see, the first parameter of the container is the query and the second is the config. We can get the `$id` from the config. Note: since React Native support `decorators` syntax, I will use it.

You’ll notice that we specify the variables called `id` on the `options` section. It will get injected into the query and will be read by grapqhl query as `$id` on runtime.

React-Apollo will wrap the query result inside the `props.data`. If you want to get the result, you can access it via `this.props.data` object. For this example, we have `film` object for the query. React-Apollo will inject the `film` object into `props.data`. So we can access it by using `this.props.data.film`.

The `data` prop has some other useful properties which can be accessed directly from `data`. For example, `data.loading` or `data.error`. Please do check the `data.loading` and `data.error` before render the page. Logically, you can show the loading bar if `data.loading` is `true` or you can show the error message if `data.error` is not `null`.

You can check the fully working example on here.