Are you interested in building a React Native app that uses GraphQL API endpoints? Then you should read this tutorial. You are going to learn how to leverage Apollo to build a client-side GraphQL application with React Native and Expo.
Apollo has an entire ecosystem to build GraphQL applications. You can use it to develop client-side and server-side apps separately. Apollo has more features and support than its open-source competitors in GraphQL for JavaScript world.
Getting Started
To start, create a new React Native app using the following command:
https://gist.github.com/3054bd53d9f76f300877f1ec514833da
Now, let us install all the npm dependencies that are going to be used in this demo app. You will learn about each individual dependency whenever necessary in the rest of the tutorial. Do note that, some of these dependencies are peer dependencies and you might not use them directly.
https://gist.github.com/9d7827960d7caa4f9f7916deeee5175d
After all the dependencies are installed, let us add a header component inside App.js
file and replace the rest of the contents that come by default with the Expo app.
https://gist.github.com/349149141e36d887f8745c760595fd6e
Just to see if everything works, go back to the terminal window and run the command yarn start
that triggers the Expo client app to run. Press i
if you are using an iOS simulator or a
if you are using an android emulator.
You will get the following output when the App component renders for the first time:
[ss1]
Configure Apollo Client in React Native app
Create a new file called Client.js
inside src/graphql
. This file is going to contain configuration regarding the Apollo client. The apollo-client
package along with apollo-cache-inmemory
and apollo-link
is a fully-featured GraphQL client that can be integrated into React or React Native apps.
To start open the newly created file and import the following statements.
https://gist.github.com/a7c2395892c0d12f836237fbfb8622d2
The apollo-link-rest
package allows you to use third-party APIs that do not have GraphQL endpoints or have REST endpoints but what you want to transmit them into GraphQL.
The API endpoint you are going to use for this tutorial is a REST endpoint and is known as News API. Make sure to get the API key by logging in here (it's free).
Add a RestLink for the Rest API endpoint and pass headers
which is an object representing values to be sent as headers on the request. The value you need to sent while requesting data from the API endpoint is the API key.
https://gist.github.com/526d788d0551b8a8ee1ab5f512c21097
Next, add the following configuration with the default cache and RestLink
to complete the configuration of Apollo Client.
https://gist.github.com/23dc53f96bd1c778f96dd998fe7aaec9
Making a request to REST endpoint with Apollo
In this section, let us write a query to hook the Apollo Client to fetch results from the REST API endpoint. However, the query is going to be made in GraphQL query language with the help of graphql-tag
.
In the src/graphql
directory, create a new file called Queries.js
and import graphql-tag
.
https://gist.github.com/d763435cc3db44476d0b3d23e360081c
Next, export using template from gql
tag, add a query that is going to fetch top headlines from the News API. Using the @rest
directive Apollo manges how to parse this query.
https://gist.github.com/f68915ab3c15cf163b0f85e419d4f0b7
To use the query, import it inside App.js
file along with the configured Apollo client by adding the following two import statements.
https://gist.github.com/ed11a50bb45520ac542af28329ea8d03
The query should run whenever the component is going to mount, thus, using the life-cycle method componendDidMount
you can invoke the query to fetch results. For now, let us log the result in a console.log
statement and see what results the endpoint provides.
The requestHeadlines()
function is going to invoke the query using Apollo Client. Invoking the query is simply done adding a promise.
https://gist.github.com/08c1fc9dafdbeafe1677207ba3b13a56
With Expo client, there is an option to Debug JS remotely. It opens the console tab in browser's developer tools and lets you see results of log statements (just like in web development).
Here is the result of the above query. When invoked, it fetches 20 headline objects in an array with all requested fields.
[ss2]
Adding an activity indicator
Take a clear look at the above image in the previous section, in the response, you will find a field called loading
that tells the app that the query is done fetching the data. This can be helpful when adding an activity indicator to display the same message to the end user in a real mobile app.
Import the ActivityIndicator
component from react-native and add the following state to the App
component.
https://gist.github.com/5de7251be0d7feb341565ef78e08e03a
Next, modify the render method to show the activity indicator component when the state variable loading
is true.
https://gist.github.com/aad581dbf63a3c16a1c0f3f957620382
You will get the following output:
[ss3]
To make it stop and behave in the way the app requires, update the state of loading
when the promise resolves inside the query method.
https://gist.github.com/2ce768af90c15afc071210aa9e7e7743
Refresh the Expo client and you will notice that after a few seconds, when the data is fetched, the loading indicator disappears and the screen UI is displayed as before.
Displaying articles from the API
You are all set to display individual article component that is being fetched from the API endpoint. Add another variable to the state object called articles
. To render a list of data, let's use FlatList
component from react-native.
https://gist.github.com/589862fd483f33141b7ac709fc050cc4
Next, update the articles
state with the array from the response when the promise gets resolved.
https://gist.github.com/55f0f73b45b5ba7b5bc2aa7f1afa5e59
The FlatList
component requires three attributes to render a list of data items.
data
: an array of data which is provided by the state variablearticles
.renderItem
: that contains the JSX for each item in the data array for which let's create a new component calledArticle
in a separate file in the next section.keyExtractor
: used to extract a unique key for a given item at the specified index for which let's use each article's URL for that is going to be unique.
That said, modify the render
function as below:
https://gist.github.com/a7bff033d62eb8d986aea17be951dcad
A little modification to the styles as well:
https://gist.github.com/627fd58ef6979e45bcccd5168a4b1752
Creating Article component
Inside src/components
directory create a new file called Article.js
. For now, this component is going to display the title and source of each headline.
The Article
component is going to be a presentation component that receives everything from the App
component as props. Add the following to the file.
https://gist.github.com/c273b71e0a0f65e1066cdbd47cb315db
How can you title
and source
are getting destructured? This is because in the App.js
file when passing the item
inside the renderItem
attribute of FlatList
component, you have already destructured the item
using spread operator.
https://gist.github.com/b4fda04ad44168f2e65f328439eec5a0
Import the Article
component in App.js
file for its work.
https://gist.github.com/199cc24c9edc85f03d9a9f16fa7f7f54
Now, go back to the simulator in which you are running the Expo client and you will get a similar result as the following.
[ss4]
Conclusion
Congratulations! You have successfully integrated an Apollo client and converted a REST endpoint to query using GraphQL query language. I hope you have fun reading this introductory tutorial that covers an important aspect of React Native development with GraphQL.