All posts
8 October 2026·8 min read

Learning React Native: A Practical Roadmap

What to learn, in what order, and which traps to avoid when you're starting out building iOS and Android apps with React Native.

#react-native#react#mobile#expo#learning

React Native lets you build real iOS and Android apps with React and TypeScript. It's not a web page in a wrapper: your components render to genuine native views, so a <View> becomes a UIView on iOS and a ViewGroup on Android.

That makes it one of the most practical ways into mobile development, especially if you already know React. But mobile has its own rules, and a lot of the frustration beginners feel comes from treating a phone like a small browser.

This post is the roadmap I'd follow if I were starting today: what to learn, in what order, and what to watch out for.


Step 0: Get Comfortable with React and TypeScript

React Native is React. Before touching mobile, make sure you're comfortable with:

  • Function components, props, and JSX
  • useState, useEffect, useMemo, and useCallback
  • Lifting state up and passing callbacks down
  • TypeScript basics: types for props, state, and API responses

If you've built a small React web app, you're ready. If you haven't, spend a week on that first. It will make everything else much easier.


Step 1: Start with Expo

The React Native docs recommend starting with a framework, and Expo is the standard choice. It handles the painful parts of native tooling for you: build configuration, native modules for the camera, location, notifications and more, plus over-the-air updates and cloud builds.

npx create-expo-app@latest my-first-app
cd my-first-app
npx expo start

Scan the QR code with the Expo Go app on your phone and your app is running on a real device in under a minute. Edit a file, save, and it updates instantly.

A common worry is that Expo will limit you later. These days that's rarely true. With development builds you can add any native library and still keep Expo's tooling. You don't need to "eject."


Step 2: Unlearn the DOM

This is where web developers stumble most. There's no HTML and no CSS files. Instead you get a small set of core components:

WebReact Native
<div><View>
<p>, <span><Text> (all text must be inside <Text>)
<img><Image>
<button><Pressable>
<input><TextInput>
Scrolling <div><ScrollView> or <FlatList>

Styling uses JavaScript objects, with a subset of CSS and Flexbox for layout:

import { useState } from "react";
import { Pressable, StyleSheet, Text, View } from "react-native";

export function Counter() {
  const [count, setCount] = useState(0);

  return (
    <View style={styles.container}>
      <Text style={styles.count}>{count}</Text>
      <Pressable
        onPress={() => setCount((c) => c + 1)}
        style={({ pressed }) => [styles.button, pressed && styles.pressed]}
      >
        <Text style={styles.buttonText}>Tap me</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, alignItems: "center", justifyContent: "center", gap: 16 },
  count: { fontSize: 48, fontWeight: "700" },
  button: { backgroundColor: "#4f46e5", paddingHorizontal: 24, paddingVertical: 12, borderRadius: 999 },
  pressed: { opacity: 0.7 },
  buttonText: { color: "white", fontSize: 16, fontWeight: "600" },
});

A few things that catch people out:

  • Flexbox defaults to column, not row like on the web.
  • Units are density-independent pixels. You write 16, not "16px" or "1rem".
  • Styles don't cascade. A <View>'s font settings don't apply to the <Text> inside it. Nested <Text> is the one exception.
  • Strings outside <Text> crash the app. A stray space or {count} sitting directly inside a <View> will throw an error.

Step 3: Navigation

Mobile navigation works differently from web routing. Screens are stacked on top of each other, with tabs, modals, and gestures like swipe-to-go-back.

If you're using Expo, start with Expo Router, which uses file-based routing like Next.js:

app/
├── _layout.tsx          # root stack
├── (tabs)/
│   ├── _layout.tsx      # bottom tab bar
│   ├── index.tsx        # Home tab
│   └── profile.tsx      # Profile tab
└── product/[id].tsx     # pushed on top of the tabs
import { Link } from "expo-router";

<Link href={`/product/${product.id}`}>View details</Link>

Under the hood it's built on React Navigation, the long-standing community standard, so what you learn carries over either way. Spend time understanding the difference between stack, tab, and modal navigation. Getting this structure right early saves a lot of rewriting later.


Step 4: Lists, Data, and Performance

Almost every app is mostly lists. Learn FlatList early, and never render a long list with .map() inside a ScrollView:

<FlatList
  data={products}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => <ProductRow product={item} />}
  ItemSeparatorComponent={Divider}
  onEndReached={loadMore}
  refreshing={isRefreshing}
  onRefresh={refresh}
/>

FlatList only renders what's on screen (plus a small buffer), which keeps memory and frame rate under control. For very long or complex lists, look at FlashList from Shopify.

For fetching data, a library like TanStack Query handles caching, retries, background refetching, and loading states. That's especially valuable on mobile, where networks are slow, flaky, or missing entirely.

Performance habits worth building from day one:

  • Keep list items light, and use React.memo for rows that re-render often.
  • Avoid heavy work in render. Move it into useMemo or off the main thread.
  • Use Reanimated for animations so they run on the UI thread and stay smooth.
  • Test on a real, mid-range Android device. The simulator on a fast laptop hides problems your users will feel.

Step 5: Think Like a Mobile Developer

This is the step most tutorials skip, and it's what separates an app that works from one that feels native:

  • Safe areas. Notches, rounded corners, and home indicators. Use react-native-safe-area-context so content isn't hidden under them.

  • The keyboard. It covers your inputs. Learn KeyboardAvoidingView or a keyboard-aware scroll library.

  • Platform differences. iOS and Android users expect different things. Use Platform.OS or Platform.select when it matters:

    const shadow = Platform.select({
      ios: { shadowColor: "#000", shadowOpacity: 0.1, shadowRadius: 8, shadowOffset: { width: 0, height: 4 } },
      android: { elevation: 4 },
    });
    
  • App lifecycle. Apps get backgrounded, suspended, and killed. Use AppState to refresh data when the user returns.

  • Offline and slow networks. Show cached data, handle failures gracefully, and never leave a spinner running forever.

  • Permissions. Ask for camera, location, or notifications at the moment they're needed, with a clear reason, not all at once on launch.

  • Secure storage. Tokens belong in the iOS Keychain or Android Keystore (for example via expo-secure-store), not in AsyncStorage.

  • Accessibility. Add accessibilityLabel and accessibilityRole, support dynamic font sizes, and try your app with VoiceOver and TalkBack.


Step 6: Understand What's Under the Hood

You don't need to write native code to be productive, but understanding the architecture helps you debug and make good decisions.

React Native's New Architecture is now the default. In short:

  • Your JavaScript runs on Hermes, a JavaScript engine built for React Native that starts fast and uses little memory.
  • JSI lets JavaScript call native code directly, replacing the old asynchronous "bridge" that serialised every message to JSON.
  • Fabric is the new rendering system, and TurboModules load native modules lazily, only when they're first used.

Practically, this means smoother UI and faster startup, and it's worth checking that the libraries you choose support the New Architecture.

Eventually you'll want to read a bit of Swift and Kotlin too. Not to rewrite your app, but to understand a native library's source, read a crash log, or write a small native module when you need a platform feature no library covers.


Step 7: Ship It

Building an app and releasing an app are two different skills. Learn the release process early, not the week before launch:

  • EAS Build creates signed iOS and Android builds in the cloud, so you don't need to fight local certificates on day one.
  • TestFlight (iOS) and internal testing tracks (Google Play) get your app onto testers' phones.
  • Over-the-air updates (EAS Update) let you ship JavaScript fixes without a store review. Use them for fixes, not to sneak in major features.
  • Crash reporting with a tool like Sentry tells you what's breaking for real users.
  • Store listings need screenshots, privacy details, and a description. Allow time for App Store review, especially for your first submission.

A Realistic Learning Plan

WeekFocusBuild this
1Core components, styling, FlexboxA static profile screen and a counter
2NavigationA tab app with a list screen and a details screen
3Data and listsFetch from a public API with FlatList, pull-to-refresh, and loading/error states
4Native featuresAdd the camera or location, with proper permission handling
5PolishSafe areas, keyboard handling, dark mode, accessibility
6ShipBuild with EAS and get it onto TestFlight or a Play internal track

Like any skill, the key is one project that grows rather than a dozen half-finished tutorials. By week six you'll have a real app on a real phone, and you'll understand every part of it.


Common Beginner Mistakes

  • Rendering long lists with ScrollView and .map() instead of FlatList.
  • Only testing on the iOS simulator, then discovering Android looks different.
  • Ignoring the keyboard, safe areas, and small screens until the end.
  • Installing a library for everything. Each native dependency is something you'll need to keep updated.
  • Storing auth tokens in AsyncStorage instead of secure storage.
  • Treating the app like a website: expecting hover states, mouse input, and constant connectivity.

Wrapping Up

React Native is a great way to build mobile apps, especially if you already know React. The JavaScript is the easy part. The real learning is in thinking like a mobile developer: designing for touch, small screens, unreliable networks, and two platforms with their own conventions.

Start with Expo, build one app that grows week by week, test on real devices, and ship something to a real store. That's when it all clicks.


Thanks for reading! If you're learning React Native, I'd love to hear what you're building.

Written by

Niluka Bandara

Lead Mobile Developer in Stockholm, building Flutter apps for fintech and payments.