DEV Community

Cover image for React Native Apollo GraphQL
kpiteng
kpiteng

Posted on

React Native Apollo GraphQL

Discover Apollo Client | State Management Library Local & Remote Data With GraphQL | Fetch, Cache, Update Data | Step by Step Integration | Download Source Code

Hello Developers, Many of us using State Management libraries like Redux, Redux Saga, Rematch, MobX, Apollo Client is one of the popular state management library with a stack of features. Today, we will discuss the Apollo Client library and see how it communicates with servers using GraphQL and manages both local and remote data. We will cover the step by step process to communicate GitHub GraphQL API and search list of GitHub repositories.

Dependency Installation -

/*
* @apollo/client
* graphql
* apollo3-cache-persist
*/
npm i @apollo/client graphql apollo3-cache-persist
Enter fullscreen mode Exit fullscreen mode

@apollo/client — package contains everything you need to set up for Apollo Client. It includes state management, cache, error handling.
graphql — package parsing GraphQL queries
apollo3-cache-persist — package persist your data in AsyncStorage

Initialize ApolloClient -

Let’s first import all required dependency

mport {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  useQuery,
  gql
} from "@apollo/client";
Enter fullscreen mode Exit fullscreen mode

ApolloClient — create client object to communicate with server
InMemoryCache — cache instance to cache query results
ApolloProvider — place Apollo Client on the Context
useQuery — execute query with variables
gql — GraphQL query

const httpLink = createHttpLink({
  uri: 'https://api.github.com/graphql',
});

const authLink = setContext((_, { headers }) => {
  const token = "ghp_xxxxxxxxxxxxx"; // replace your github personal access token here
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    }
  }
});
const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache,
  defaultOptions: { watchQuery: { fetchPolicy: 'cache-and-network' } },
})
Enter fullscreen mode Exit fullscreen mode

Lets’ understand what we did over here,

Basically ApolloClient requires two arguments, link (server link) — in developer terms API EndPoint/BaseURL, cache — memory cache of your response. Over here we have a bit twist. We are calling the GitHub API which requires AccessToken to communicate API, so we generate a token from GitHub and place it in the header. If you have an Open API then no more need of headers.

Steps to get GitHub Personal Access Token —
Github Login > Settings > Developer Settings > Personal Access Tokens — Give Descriptive Name — CheckMark repo, admin:repo_book (read:repo_hook), delete_repo and press Generate Token.

Connect Apollo Client to React Component -

<ApolloProvider client={client}>
 <GitRepository />
</ApolloProvider>
Enter fullscreen mode Exit fullscreen mode

All you know about React Context API. Here, we connect Apollo Client with ApolloProvider, so the client will be available in all child components — component tree.

Construct the Query -

const fetchRepository = gql`
query SearchMostTop10Star($queryString: String! $afterCursor:String) {
  search(query: $queryString, type: REPOSITORY, first: 10, after: $afterCursor){
    repositoryCount
    edges {
      node {
        ... on Repository {
          name
          descriptionHTML
        }
      }
      cursor
    }
  }
}
`
Enter fullscreen mode Exit fullscreen mode

We want to search for a GitHub repository. So we have passed two arguments in the query, queryString — whatever user search on TextInput will be applied on search, after — cursor position — each time we send the current cursor position, so query will fetch next 10 records after that cursor point.

Design Component -

<View style={Styles.repositoryInputContainer}>
  <TextInput
    style={Styles.repositoryTextInput}
    placeholder="Enter your text here"
    onChangeText={text => setSearchText(text)}
    onEndEditing={(e) => endEditing(e)}
    clearButtonMode="while-editing"
  />
</View>
Enter fullscreen mode Exit fullscreen mode

Let’s first add TextInput — which allows the user to enter a repository name and onChangeText we will store text into State, onEndEditing we will dispatch a query.

<FlatList
  data={arrRepository}
  renderItem={({ item }) => (
    <GitRepoItem
      repository={item}
    />
  )}
  keyExtractor={(x, i) => i.toString()}
  keyExtractor={(repository, i) => `${repository.cursor}-${i}`}
  ListFooterComponent={<FooterView />}
  ItemSeparatorComponent={() => ItemSeparatorComponent()}
/>
Enter fullscreen mode Exit fullscreen mode

FlatList will list all repositories.

const { data } = useQuery(fetchRepository, {
  variables: cursorVariable
});
/*
* cursorVariable: { "queryString": "react native" }
*/
Enter fullscreen mode Exit fullscreen mode

Now, it’s time to execute a query, here we will send a few arguments in variables. This is the initial Query Call when the component didMount so we will send { queryString: “React”} — so it will look like — variables: { “queryString”: “react” }. So what happens if we execute this query, it will return us a list of Repositories that contain name react. Each repository contains node name, htmlDescription, cursor (cursor position). Now we have a list of Repositories in FlatList — Now lets scroll down and see all first 10 repositories. Initially we haven’t passed after keyword so it will fetch first 10 repositories, Now what happen if you want to fetch next 10 record then,

So Let’s add onEndReached — It will be invoked when the user reaches the end of FlatList.

<FlatList
  data={arrRepository}
  renderItem={({ item }) => (
    <GitRepoItem
      repository={item}
    />
  )}
  keyExtractor={(x, i) => i.toString()}
  keyExtractor={(repository, i) => `${repository.cursor}-${i}`}
  ListFooterComponent={<FooterView />}
  ItemSeparatorComponent={() => ItemSeparatorComponent()}
  onEndReachedThreshold={0.1}
  onEndReached={() => { 
    if (!dataLoading) {
      dataLoading = true;
      setCursorVariable({
        "queryString": searchText,
        "afterCursor": (arrRepository.length > 0) ? arrRepository[arrRepository.length - 1].cursor : ''
      });
    }
   }}
/>
Enter fullscreen mode Exit fullscreen mode

We have added onEndReached — to fetch the next 10 repositories from GitHub by sending the cursor position in the query parameter. Over here in queryString we will send searchText (user entered in TextInput), after — cursor value (cursor position) — which we will receive in the query response. So the query will return us the next 10 records. That’s it.

So, it’s quite simple in understanding and integrating. GraphQL makes your task simple, you can customize query according to your business logic and your convenience.

Please download source code from here.

Thanks for reading Article!

KPITENG | DIGITAL TRANSFORMATION
www.kpiteng.com/blogs | hello@kpiteng.com
Connect | Follow Us On - Linkedin | Facebook | Instagram

Discussion (0)