Lesson 2 of 7 · 35 min

React Native Navigation and State Management Explained

Structure screens with typed navigation and keep state manageable by separating server state from client state.

In this lesson1. Planning navigation2. Typed routes and parameters3. Server state versus client state4. Keeping screens fast and simple

Planning navigation

Before writing screens, sketch the navigation structure on paper. Most apps combine a few patterns: a stack for drilling into details, tabs for the main sections and a separate authentication flow shown before sign-in. A field sales app might have tabs for Today, Customers and Orders, with each tab holding its own stack. Drawing this first prevents awkward rewrites when you discover that a screen needs to be reachable from two places.

React Navigation is the most widely used library for this in React Native, and Expo Router builds file-based routing on top of it. Whichever you use, model the authentication flow by rendering different navigators depending on whether the user is signed in, rather than navigating to a login screen and hoping users cannot go back. This conditional pattern is described in the React Navigation authentication guide and avoids a whole class of back button bugs.

Typed routes and parameters

Type your route parameters so the compiler catches mistakes. If the order detail screen needs an order ID, the type system should refuse a navigation call without one. Pass identifiers in parameters, not whole objects. Passing a full order object makes deep links harder, can go stale when the data changes and bloats navigation state. The detail screen should fetch or read the order by its ID from your data layer.

Keep screen components thin. A screen should read its parameters, call hooks that fetch or select data and pass results to presentational components. Business rules, formatting and API calls belong in hooks and modules that can be tested without rendering a screen. This separation also makes it easier to reuse logic if the same data appears in a tab and in a modal, or if you later share code with a web app.

typescript · illustrative
// Illustrative TypeScript. See reactnavigation.org and the
// state library's own docs for current APIs.
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { create } from 'zustand';

export type RootStackParamList = {
  OrderList: undefined;
  OrderDetail: { orderId: string };
};

export const Stack = createNativeStackNavigator<RootStackParamList>();

type SessionState = {
  token: string | null;
  signIn: (token: string) => void;
  signOut: () => void;
};

// Small global store for client state only
export const useSession = create<SessionState>()((set) => ({
  token: null,
  signIn: (token) => set({ token }),
  signOut: () => set({ token: null }),
}));

// In a screen: navigation.navigate('OrderDetail', { orderId: '42' })

Server state versus client state

The biggest state management mistake in mobile apps is putting everything in one global store. Most data in a typical app is server state: orders, customers, products and messages that live on your backend and are only cached on the device. It needs fetching, caching, refreshing and invalidation. Client state is different: the signed-in session, a selected filter, a draft form or a theme preference. It belongs to the device and changes only when the user acts.

Treat these two kinds of state with different tools. A data fetching library such as TanStack Query handles server state with caching, background refresh and retries built in. A small store such as Zustand, Redux Toolkit or plain React context handles client state. Once server data moves out of the global store, the store often shrinks to a handful of values, and the app becomes much easier to reason about and test.

  • Server state: lists, details and anything the backend owns
  • Client state: session, preferences, UI selections and drafts
  • Local component state: values that only one screen needs

Keeping screens fast and simple

Keep state as close as possible to where it is used. A text input value that only one form needs should live in that component, not in a global store, because global updates can cause many components to re-render. When using a global store, subscribe to small slices of state with selectors instead of the whole object. This matters more on mobile than on the web, because low-end phones feel every unnecessary render.

Finally, persist only what you must. Session tokens belong in secure storage provided by the platform keychain or keystore, through a library such as Expo SecureStore, not in plain async storage. User preferences can be persisted in normal storage. Cached server data can be persisted for offline use, which the next lesson covers. Review what you persist with the same care you give to an API design, because it becomes part of your app's contract with returning users.

Key takeaways
  • Sketch the navigation structure before building screens
  • Render separate navigators for signed-in and signed-out users
  • Type route parameters and pass IDs instead of whole objects
  • Use a data fetching library for server state and a small store for client state
  • Keep tokens in secure storage and state close to where it is used
Try it

Draw the navigation map for an app with an authentication flow, three tabs and at least one detail screen per tab. Implement typed route parameters for the detail screens. List every piece of state in your app and label each one as server, client or local component state.

Check your understanding

1. What should you pass when navigating to a detail screen?

2. Which of these is server state?

3. Where should a session token be stored on the device?

← PreviousExpo vs Bare React Native: How to Set Up a New ProjectNext lesson →React Native API Integration, Offline Support and Caching
XDQ xAgents · AI lab for your company
While you sleep, your AI agents keep working.

From USD 49 or INR 2,999 a month. A person approves every step.

Start free, 14 days →See every agent300 credits · no card needed · prices include taxes🚀 Startup? Free landing page for 30 days →Need custom software or a security review? Send a brief →