React Native + GraphQL (using Apollo)-Pokédex

Muhammad Hanif
8 min readDec 1, 2020

--

GraphQL is a better choice than restAPI because there are several advantages, especially in terms of performance and efficiency when requesting specific data from clients. There are so many explanation about it (just googling), you can read from here (indonesian), here (english) and here (english).

I won’t explain much about the GraphQL concept or fundamentals. I will explain about how to fetch data using GraphQL from client by using Apollo. Then, there are the conditions (state) like redux that we can use in Apollo, it is simpler and really helpful to be implemented in Atomic Design concept.

Pokédex Design on Dribble

If we want to learn about GraphQL, we must search the free and public APIs that can be consumed. It is one of them, GraphQL Pokemon or here a collective list of public GraphQL.

Requirements
*
Nodejs
* Watchman
* NPM or Yarn
* Cocoapods (Optional)
* Android Studio & Xcode (Optional)
* React Native v0.63 or above
* React Navigation v5 or above

Installing Dependencies
First of all, we have to create project template by running syntax

npx react-native init Pokédex

Then, move to our directory project

cd Pokédex

For the Apollo and GraphQL dependencies we run this syntax. In the newest Apollo dependency, core of @apollo/client is already included the other part, like {ApolloClient, ApolloProvider and InMemoryCache}. For the hooks, we can import {useQuery and gql} from @apollo/client itself.

npm install — save @apollo/client graphql

React Navigation that we use is the React Navigation v5 or above. We install the core of React Navigation & React Navigation Stack. Then, the other dependencies that build them, like screens, reanimated, etc must be installed too. Here is the syntax for install them.

react navigation dependencies

Last, this is optional, my dependencies for project template that I usually use.

optional dependencies

Install Dependencies for iOS
For iOS, we must install from cocoapods by running this syntax in our root project template.

cocoapods for iOS

Folder Structure
For the folder structure, you can see from here. It is the folder structure that I usually use for the project template. But, in Apollo we don’t have to define our redux, so the folder structure will be like this. Folder actions and redux is not included in this project.

folder structure

GraphiQL
Before we bind our data from fetching GraphQL, we need to know first the form of syntax/query of GraphQL and the object response from GraphQL. We can use GraphiQL to see the query and response. It is the example of query and data response from GraphQL for fetching 100 pokemons data.

query and response to get 100 pokemons

Then, to get the detail information of each pokemon, we can use this query by passing the ID. We will get all the data that we want.

query and response to get detail information of each pokemon by ID

react-native.config.js
This file is to config our fonts, so it can be used in Android/iOS. You can see the ultimate guide to custom fonts in react native.

index.js
Our index.js file is the same as the react native template.

index.js in the root project

App.js
In App.js, we config our client first by define it in function ApolloClient. The params are uri and cache. For the uri, you can use your uri link by hosting from the public API. Cache param defines the function InMemoryCache. If we want to replace the data that already fetched from GraphQL, we must define prop merge(existing, incoming){return incoming}

App.js in the root project

ApolloProvider is used to wrap the Router and it has props client, connect that client, so it can be called in every routes/pages.

Routes
In Routes folder, we create index.js file. In newest React Navigation v5, we must define createStackNavigator function andNavigationContainer will be the root container of our pages.

index.js inside Routes folder

Pages
In Pages, we create 4 files (Home.js, Empty.js, Splash.js and Detail.js). To config all our pages, we also create 1 file index.js, so it will be easy if we want to call it from other pages or class.

Home.js

Home.js inside Pages folder

Empty.js

Empty.js inside Pages folder

Splash.js

Splash.js inside Pages folder

Detail.js

Detail.js inside Pages folder

index.js

index.js inside Pages folder

constants/query
In Constants folder, create folder “query” and create file index.js inside it. For the query, we have 2 functions: allpokemon and infopokemon. Get all pokemons will fetch the first 100 pokemons data and it will return id, number, name, types and image. Info pokemon is called when we click the detail of each pokemon by passing the id param and it will return all of pokemons data, like id, number, name, classification, maxCP, maxHP, etc (it’s up to you).

index.js inside Query folder

Configs
Configs folder will be really helpful to store our configuration like colors, fonts, images, sizes and strings.

configs/colors
In Configs folder, we create Colors folder, then we create index.js file.

index.js inside Colors folder

configs/fonts
Then in Configs folder we also create fonts folder, inside of it we create index.js file. In this project I use font Nunito, you can download here.

index.js inside Fonts folder

configs/images
For images configuration, we create Images folder inside of Configs folder. Then create index.js file there.

index.js inside Images folder

configs/sizes
If we want to config our text size or any value of size, we can create Sizes folder inside of Configs folder, then create index.js file.

index.js inside Sizes folder

configs/strings
Strings will be useful if we want to store large text or static text that will be used over and over.

index.js inside Strings folder

index.js
Lastly, to call all configurations function, we need index.js file to store them.

index.js inside Configs folder

Components
As I explained in the beginning, Apollo Client in React is really helpful to handle state, we don’t have to create one by one all of states, like redux. So, for the components we have 4 components: EmptyState, Loader, PokemonInfo and PokemonList

EmptyState.js
EmptyState will be used in some conditions, for example if the data fetching is error/failed (error state), we can use this component. Or maybe if the data is [] or null, we can render this component.

EmptyState.js inside Components folder

Loader.js
Loader component will be used for every fetching data in loading state.

PokemonInfo.js
PokemonInfo is used to render the pokemon information and we divide it into 4 tabs: About, Base stats, Attacks and Evolutions.

PokemonInfo.js (1) inside Components folder
PokemonInfo.js (2) inside Components folder

PokemonList.js
PokemonList component renders the list of all pokemon in Home page. There is the filter to see list in grid/column mode.

PokemonList.js in Components folder

index.js
Finally, index.js inside the Components folder is to config all components and can be called in a function or class publicly.

index.js in Components folder

Result!
Here is the result of our project.

Final result of Pokédex
Splash Screen
UI in Page Home

In Page Home, there will be 100 pokemons. We can change our list by clicking the filter icon in top right, grid/column.

UI in Detail Page

After clicking the pokemon card, it will navigate to Detail page. In Detail page, there are the information that divided into 4 tabs. Also, we can hit the like button in heart icon. If that pokemon has evolutions, we can also click it and it will navigate to the other detail page of its evolution.

Empty State

Empty state page will be like this. When there is the error or no data found.

So, the GraphQL with Apollo in React Native is the good combination for fetching the specific data. Also, the performance is better than restAPI. But, it doesn’t mean that GraphQL is the best method that can always use, it all depend of our needs. I hope this article will be useful to those of you who are trying to implement GraphQL in React Native. Apollo is just one of the platform for communication between clients and backend services, you can use other platforms.

--

--

Muhammad Hanif

Frontend Developer @Telkomsel. Part-time Runner @10.11Runners. Retail Investor @TLKM. Sport & Technology enthusiast.