Skip to main content

Apollo vs Redux State

This page helps you decide where state belongs: Apollo cache + generated GraphQL hooks for server-state, and Redux Toolkit slices for client/UI flow state.

How it works

I like to think in terms of “what owns the source of truth”:

1) Server-state: generated hooks + Apollo cache

When you call a use*Query / use*Mutation hook from apps/portal/src/gql/hooks.ts, Apollo manages loading/error/data and caches results in InMemoryCache.

2) Client-state: Redux Toolkit slices

Redux is used for “what the user is doing right now”:
  • selected product / quantity during checkout
  • wizard steps
  • local UI toggles that don’t need to be shared across tabs
The Redux store is created in: apps/portal/src/redux/store.ts For example:
The checkout example state lives in: apps/portal/src/redux/slices/checkoutSlice.ts

Extending this system

Use this recipe when you add client/UI flow state and wire it into Redux.
  1. Decide if the state is server-state or client-state.
Example rule of thumb:
  • if it comes from the API, it belongs in Apollo cache (via generated hooks)
  • if it drives UI flow, it belongs in Redux
  1. Add a slice (or extend checkoutSlice) in apps/portal/src/redux/slices/.
Example: apps/portal/src/redux/slices/checkoutSlice.ts already contains checkout UI state like product, quantity, and billingAddress.
  1. Register the slice reducer in apps/portal/src/redux/store.ts.
  2. Use Redux selectors/actions from the components that need them.
  3. Verify:

What not to do

These anti-patterns lead to duplicated “state sources” and brittle UI behavior. ❌ Never duplicate server-state into Redux when Apollo cache can serve it. ❌ Never use Redux as a “second cache” for GraphQL responses. ❌ Never move API-derived entitlements, scopes, or billing rules into Redux; those are server-side rules and UI should follow the GraphQL contract.

File conventions

This section keeps Redux wiring and slice locations consistent. Prefer:
  • Keep slice state normalized and explicit.
  • Use generated hook data as read-only inputs to your UI logic.

What’s next?

If you’re adding UI flow, you’ll likely also add forms and error UX.