Not only is state management one of the most important aspects of building the front-end for your application, it's also one of the most challenging. With a REST and NGRX / Redux workflow, you're writing action creators, reducers, and selectors for each network request. For a production-level app, you're also juggling several middleware packages for features like optimistic updates and manually normalizing your data.
With a GraphQL and Apollo workflow, you just write queries and let Apollo Client take care of the rest. Apollo Client normalizes and caches your data out of the box with zero configuration. It also enables you to execute complicated features such as optimistic UI, polling, and pagination with only a few lines of code.
If we're using Apollo Client to manage our remote data, then what do we do with local data such as boolean flags and device API information that we'd like to access globally? This is where
Apollo Client comes in, our solution for local state management that allows you to use your Apollo cache as the single source of truth for data in your application. We recommend managing all of your local and remote data with Apollo Client so GraphQL becomes a unified interface to all of your application's data.
The following sections outline some tips to help you make the most of your transition to managing all of your state with Apollo Client.
Colocate queries with components
When you first start using
Apollo service for your GraphQL data, it can be tempting to dump all of your queries in one file similar to how developers using Redux put all of their reducers in a single file. Instead, we recommend that you colocate your GraphQL queries with the components that are using them. One of the greatest strengths of GraphQL is its declarative approach to data fetching, which you lose when you have to switch back to another file in order to determine what the shape of your data prop looks like:
In this example, we place our
GET_DOG_PHOTO query next to our
DogPhoto component and wrap it with the
Move data transformation to the backend
Your GraphQL schema should always reflect how you're consuming the data on the front-end. This is why we recommend that product teams own the design of their GraphQL schema. Shifting to this mentality is a bit of a departure from REST, where front-end developers consume APIs dictated by the backend team and often have to filter and sort the data into the shape their UI components expect.
If you find yourself sorting or filtering the data you receive back from your GraphQL API, it's probably a sign that you need to move that logic to your resolvers instead. Moving filtering and sorting logic to the backend ensures that you can share it across platforms easily instead of duplicating these efforts for every client.
Combine local and remote data
local state, you can add virtual fields to your remote data seamlessly and query them from your components by specifying a
@client directive. In this example, we’re querying the client-only field isLiked alongside our server data. Your components are made up of local and remote data, now your queries can be too! This is one of the main advantages for using Apollo Client to manage all of your application's data.