React Native + GraphQL (using Apollo)-Pokédex
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.
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
Then, move to our directory project
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.
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.
Last, this is optional, my dependencies for project template that I usually use.
Install Dependencies for iOS
For iOS, we must install from cocoapods by running this syntax in our root project template.
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.
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.
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.
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.
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}
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.
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
Empty.js
Splash.js
Detail.js
index.js
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).
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.
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.
configs/images
For images configuration, we create Images folder inside of Configs folder. Then create index.js file there.
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.
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
Lastly, to call all configurations function, we need index.js file to store them.
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.
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.
PokemonList.js
PokemonList component renders the list of all pokemon in Home page. There is the filter to see list in grid/column mode.
index.js
Finally, index.js inside the Components folder is to config all components and can be called in a function or class publicly.
Result!
Here is the result of our project.
In Page Home, there will be 100 pokemons. We can change our list by clicking the filter icon in top right, grid/column.
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 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.