State Management for Mobile
Separate client state from server state in a real app — Zustand for local UI/app state with persistence, and TanStack Query for everything that comes from a server.
Prerequisites: completed Mobile Fundamentals, comfort with React hooks (useState, useEffect).
Version note: verified against current npm and library documentation as of July 2026: zustand is at major version 5 (5.0.x). This project uses @react-native-async-storage/async-storage for Zustand's persist middleware, which is the standard, well-supported storage adapter across both Expo Go and development builds — react-native-mmkv is a faster alternative but requires a development build (it isn't supported in Expo Go), so it's called out as an upgrade path rather than the default. @tanstack/react-query is used for server-state (fetched data), which is the current mainstream pattern for separating client and server state in React Native apps.
Most "which state library should I use" debates dissolve once you separate two categories that get lumped together: client state (a theme toggle, a form draft, whether a modal is open — state your app owns) and server state (a list of posts fetched from an API — state a server owns, that you're caching a copy of). Client state changes instantly and locally; server state can be stale, needs refetching, and benefits from caching and retry logic you don't want to hand-write. This project uses Zustand for the former and TanStack Query for the latter, then persists only the client state that should survive an app restart.
Model client state with Zustand, then persist what should survive a restart
Fetch and cache server state with TanStack Query
Read both stores together in one screen
Secret Mission: Add optimistic favoriting synced to a server
Before You Go
Test what you just learned
Self-testing is one of the best ways to retain new skills. Unlock project quizzes to check your understanding.
Log in to unlock0 / 6 complete
