Amazing React Native Apps with Apollo React

When about to start writing a new React Native application, one of the first things I ask myself is “How to handle the logic within the application, and what tools should I use to communicate with the server?”.

In most cases, I’ve had REST API implemented somewhere and simply exchanged information with HTTP requests. GraphQL is a bit different, and I felt this difference from the very first time I used the technology. If you need simple CRUD functionalities in your application’s server — with GraphQL it’s really easy — you can check my tutorial on Super simple GraphQL server with Hapi.js, MongoDB and a new Apollo Server.or use some GQLaaS solutions such as scaphold.io or graph.cool.

But let’s get back to implementation. At first, I had a hard time understanding the new architecture and using Relay as a GraphQL client. While Relay is a great technology (designed by Facebook itself), and is really performant with GraphQL — it might be a bit confusing for newcomers. It also made me feel like I’ve lost some of my project’s flexibility and reusability of part of the components. For those reasons, I started looking for other solutions to handle communication with my GraphQL server. I found two other popular options — one was a library called Lokka and the other was Apollo.

Within the Apollo project there are two solutions that matched my needs. I then started my journey with the apollo-react and apollo-client libraries. They differ a bit, but both can help us achieve clean and performant code.

Apollo Client

You can imagine apollo-client as a root library, with apollo-react as a kind of extension to it. To start, we need to create an instance of ApolloClient and provide a URL to our GraphQL. I’m used to extracting it to a separate file, so that I can easily use it across the application. It’s a bit different when if you’re using apollo-react, but you’ll see that later. For now, we can just create a simple createApolloClient.js file and set up our client.

And now, depending on our needs we can call the .query() and .mutate() functions which behave like HTTP requests.

Example query:

Example mutation:

apollo-client leaves you a lot of freedom and works with every JavaScript solution you want to use within your app. However, when developing React or React Native apps, you should rather go for apollo-react, since it’s designed for React specifically.

Apollo React — Provider

React version of the Apollo library comes with a component that helps us connect our UI tree to GraphQL data. This component is called ApolloProvider and we can get it from apollo-react directly. You should wrap your main application component in the new provider, and pass client as its prop. Client creation is the same as in the example above, since one library depends on another.

As you can see, it’s super simple to do it this way. In the next steps I’ll show you how to attach data from server to our components.

Apollo React — Queries and Mutations

Thanks to our super-simple setup we can now attach queries to our components very easily. Apollo comes with graphql HOC which helps us provide data to our UI. That way we can attach data to any container or component we like. This approach helps us create very readable components — you can see all the data that your view is using and all the mutation functions you want to call within your view. If you don’t want your file to grow too much, you can consider extracting queries and mutations to another file.

As you can see, we can now access both data and mutations. This example might be a bit silly, but I wanted to show you the simplest solution.

A closer look at queries

In the example above we destructed the data prop to get some information from our query. Now I would like to tell you a bit more about the data prop that is attached to our component after calling a query. It’s a bit more complex than it was in the example above, but with complexity we also gain many handful props and functions inside our component. Things like loading state, errors, refetching and a lot of other stuff we had to take care of.

We can see data from our query here, and some additional helper fields. While I’ll leave QuerySubscription for now I would like to write a bit about other fields that can be really helpful while developing our application.

  • loading: determines if our request is pending,
  • error: error returned from server if request fails,
  • refetch: a function used to send the query to the server again,
  • startPolling: a function used to start the refetch interval (refetch requests will be send periodically),
  • stopPolling: clears the refetch interval.

Thanks to these functions, developing amazing application becomes super easy and fast.

A closer look at mutations

You already know the .mutate() function attached to our component — we can use it the way we’ve seen above, but we might have a problem with attaching multiple mutations to one component.

Fortunately, graphql HOC accepts options as a second function argument. This way, we can specify the name of a prop attached to our component, and use multiple .mutate() functions.

There are also other ways to clarify our mutations code. One of my favourite options is mapping mutate to props. This way we can have clear functions that accept only data we need, without confusing other contributors with wrapping data with variables object.

Now you can simply call .savePost(title, body) within our component.

Conclusion

Thanks to apollo-client and apollo-react packages we can create very simple and readable next-level applications. It works perfectly with React Native, but you should also consider using those packages when developing a React DOM application. You can dive deeper into Apollo docs to gain a fuller overview on the library. You can also find working examples of using Apollo with React on GitHub.

Mike.

Insights

Learn more about GraphQL

cover

Jul 19Article

The Power of GraphQL Directives

Discover how GraphQL directives streamline server-side tasks, from creating custom fields to integrating REST APIs.

cover

Nov 2Article

Setting up GraphQL With Hapi.js

Learn how to set up GraphQL with Hapi.js by reading this step-by-step guide prepared by Mike Chudziak.

cover

Mar 19Tutorial

The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model

Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.

cover

Mar 12Tutorial

Build Smarter Apps: Tool Calling & AI Orchestration Explained

Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.

cover

Mar 5Tutorial

MLC LLM + React Native: On-Device AI Without the Pain

Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.

cover

Feb 24Tutorial

Intelligent Fallbacks with Apple Intelligence in React Native

Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.

cover

Feb 10Tutorial

What Is the React Native AI SDK? A Complete Intro & Quickstart

Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.

cover

Jan 29Tutorial

Implementing an Android TurboModule with Kotlin

Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.

cover

Jan 19Tutorial

Working with Different Threads in Swift TurboModules

Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.

cover

Jan 9Tutorial

How to Add Type-Safe Constants to Swift TurboModules

Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.

cover

Dec 30Tutorial

Adding Event Emitters to Your TurboModule in Swift

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

cover

Dec 22Tutorial

Writing Your First TurboModule in Swift

Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.