Skip to main content

Command Palette

Search for a command to run...

React Native Tutorial 2026: Build iOS Android App in One Codebase

Learn: React Native Tutorial 2026: Build iOS Android App in One Codebase

Updated
•8 min read•View as Markdown
T

Welcome to TopperBlog! šŸ‘‹

I'm a tech content creator passionate about helping developers level up their careers and master cutting-edge technologies.

šŸŽÆ What I Write About: • AI/ML Engineering & LLMs • Web3 & Blockchain Development
• System Design & Architecture • Interview Preparation (FAANG) • Freelancing & Remote Work • Modern Tech Stacks (Next.js, React, Rust, TypeScript) • Performance Optimization & Best Practices

šŸ’¼ Mission: Sharing practical, actionable insights that accelerate your tech career and maximize your earning potential.

šŸ“š 15+ In-Depth Guides covering everything from earning $10k/month as a freelancer to cracking FAANG interviews.

🌐 Let's connect and grow together in this amazing tech journey!

#TechBlogger #SoftwareEngineering #CareerGrowth #WebDevelopment #AIEngineering

React Native Tutorial 2026: Build iOS & Android Apps in One Codebase

Introduction

React Native has revolutionized mobile development by enabling developers to write applications once and deploy them across iOS and Android platforms. In 2026, React Native remains one of the most popular cross-platform frameworks, powering apps for companies like Meta, Microsoft, and Shopify.

This comprehensive guide walks you through building production-ready mobile applications using a single JavaScript codebase. Whether you're a web developer transitioning to mobile or an experienced native developer exploring cross-platform solutions, this tutorial provides practical insights and actionable code examples.

Why React Native in 2026?

  • Code Reusability: Write once, deploy everywhere
  • Faster Development: Leverage JavaScript and React knowledge
  • Hot Reload: See changes instantly without recompilation
  • Strong Community: Extensive libraries and third-party support
  • Cost Efficiency: Reduce development time and resources

Setup & Installation

Prerequisites

Before starting, ensure you have:

  • Node.js (v18 or higher)
  • npm or yarn package manager
  • Xcode (for iOS development on macOS)
  • Android Studio (for Android development)
  • Basic JavaScript and React knowledge

Step 1: Install React Native CLI

npm install -g react-native-cli
# or using Expo CLI for faster setup
npm install -g expo-cli

Step 2: Create Your First Project

Option A: Using Expo (Recommended for Beginners)

expo init MyAwesomeApp
cd MyAwesomeApp
npm start

Option B: Using React Native CLI

npx react-native init MyAwesomeApp
cd MyAwesomeApp
npm start

Step 3: Run on Simulators

iOS (macOS only):

npm run ios

Android:

npm run android

Project Structure

MyAwesomeApp/
ā”œā”€ā”€ app.json
ā”œā”€ā”€ App.js
ā”œā”€ā”€ package.json
ā”œā”€ā”€ ios/
ā”œā”€ā”€ android/
ā”œā”€ā”€ node_modules/
└── src/
    ā”œā”€ā”€ components/
    ā”œā”€ā”€ screens/
    ā”œā”€ā”€ navigation/
    └── utils/

Core Features

1. Components & JSX

React Native uses the same component-based architecture as React web development:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const WelcomeScreen = () => {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Welcome to React Native</Text>
      <Text style={styles.subtitle}>Build once, deploy everywhere</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f5f5f5',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#333',
    marginBottom: 10,
  },
  subtitle: {
    fontSize: 16,
    color: '#666',
  },
});

export default WelcomeScreen;

2. State Management with Hooks

import React, { useState, useEffect } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

const CounterApp = () => {
  const [count, setCount] = useState(0);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    console.log('Counter updated:', count);
  }, [count]);

  const handleIncrement = () => {
    setCount(count + 1);
  };

  return (
    <View style={styles.container}>
      <Text style={styles.counter}>{count}</Text>
      <Button title="Increment" onPress={handleIncrement} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  counter: {
    fontSize: 48,
    fontWeight: 'bold',
    marginBottom: 20,
  },
});

export default CounterApp;

3. Navigation

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './screens/HomeScreen';
import DetailsScreen from './screens/DetailsScreen';

const Stack = createNativeStackNavigator();

const Navigation = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator
        screenOptions={{
          headerStyle: {
            backgroundColor: '#007AFF',
          },
          headerTintColor: '#fff',
          headerTitleStyle: {
            fontWeight: 'bold',
          },
        }}
      >
        <Stack.Screen 
          name="Home" 
          component={HomeScreen}
          options={{ title: 'Home' }}
        />
        <Stack.Screen 
          name="Details" 
          component={DetailsScreen}
          options={{ title: 'Details' }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default Navigation;

4. API Integration

import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, ActivityIndicator, StyleSheet } from 'react-native';

const UsersList = () => {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetchUsers();
  }, []);

  const fetchUsers = async () => {
    try {
      setLoading(true);
      const response = await fetch('https://jsonplaceholder.typicode.com/users');
      const data = await response.json();
      setUsers(data);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  if (loading) return <ActivityIndicator size="large" />;
  if (error) return <Text style={styles.error}>Error: {error}</Text>;

  return (
    <FlatList
      data={users}
      keyExtractor={(item) => item.id.toString()}
      renderItem={({ item }) => (
        <View style={styles.userCard}>
          <Text style={styles.userName}>{item.name}</Text>
          <Text style={styles.userEmail}>{item.email}</Text>
        </View>
      )}
    />
  );
};

const styles = StyleSheet.create({
  userCard: {
    padding: 15,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
  userName: {
    fontSize: 16,
    fontWeight: 'bold',
  },
  userEmail: {
    fontSize: 14,
    color: '#666',
    marginTop: 5,
  },
  error: {
    color: 'red',
    textAlign: 'center',
    marginTop: 20,
  },
});

export default UsersList;

Building Example App: Todo Application

Here's a complete todo app demonstrating core concepts:

import React, { useState } from 'react';
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  FlatList,
  StyleSheet,
  Alert,
} from 'react-native';

const TodoApp = () => {
  const [todos, setTodos] = useState([]);
  const [input, setInput] = useState('');

  const addTodo = () => {
    if (input.trim() === '') {
      Alert.alert('Error', 'Please enter a todo');
      return;
    }
    setTodos([...todos, { id: Date.now(), text: input, completed: false }]);
    setInput('');
  };

  const toggleTodo = (id) => {
    setTodos(
      todos.map((todo) =>
        todo.id === id ? { ...todo, completed: !todo.completed } : todo
      )
    );
  };

  const deleteTodo = (id) => {
    setTodos(todos.filter((todo) => todo.id !== id));
  };

  const renderTodo = ({ item }) => (
    <View style={styles.todoItem}>
      <TouchableOpacity
        style={styles.checkbox}
        onPress={() => toggleTodo(item.id)}
      >
        <Text style={styles.checkboxText}>
          {item.completed ? 'āœ“' : ''}
        </Text>
      </TouchableOpacity>
      <Text
        style={[
          styles.todoText,
          item.completed && styles.completedText,
        ]}
      >
        {item.text}
      </Text>
      <TouchableOpacity
        style={styles.deleteBtn}
        onPress={() => deleteTodo(item.id)}
      >
        <Text style={styles.deleteBtnText}>Delete</Text>
      </TouchableOpacity>
    </View>
  );

  return (
    <View style={styles.container}>
      <Text style={styles.title}>My Todos</Text>
      <View style={styles.inputContainer}>
        <TextInput
          style={styles.input}
          placeholder="Add a new todo..."
          value={input}
          onChangeText={setInput}
          placeholderTextColor="#999"
        />
        <TouchableOpacity style={styles.addBtn} onPress={addTodo}>
          <Text style={styles.addBtnText}>Add</Text>
        </TouchableOpacity>
      </View>
      <FlatList
        data={todos}
        renderItem={renderTodo}
        keyExtractor={(item) => item.id.toString()}
        ListEmptyComponent={
          <Text style={styles.emptyText}>No todos yet. Add one!</Text>
        }
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    paddingTop: 50,
    paddingHorizontal: 20,
  },
  title: {
    fontSize: 28,
    fontWeight: 'bold',
    marginBottom: 20,
    color: '#333',
  },
  inputContainer: {
    flexDirection: 'row',
    marginBottom: 20,
  },
  input: {
    flex: 1,
    borderWidth: 1,
    borderColor: '#ddd',
    borderRadius: 8,
    paddingHorizontal: 15,
    paddingVertical: 10,
    marginRight: 10,
  },
  addBtn: {
    backgroundColor: '#007AFF',
    paddingHorizontal: 20,
    borderRadius: 8,
    justifyContent: 'center',
  },
  addBtnText: {
    color: '#fff',
    fontWeight: 'bold',
  },
  todoItem: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingVertical: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
  checkbox: {
    width: 24,
    height: 24,
    borderWidth: 2,
    borderColor: '#007AFF',
    borderRadius: 4,
    justifyContent: 'center',
    alignItems: 'center',
    marginRight: 12,
  },
  checkboxText: {
    color: '#007AFF',
    fontSize: 16,
    fontWeight: 'bold',
  },
  todoText: {
    flex: 1,
    fontSize: 16,
    color: '#333',
  },
  completedText: {
    textDecorationLine: 'line-through',
    color: '#999',
  },
  deleteBtn: {
    paddingHorizontal: 10,
    paddingVertical: 5,
    backgroundColor: '#ff3b30',
    borderRadius: 4,
  },
  deleteBtnText: {
    color: '#fff',
    fontSize: 12,
    fontWeight: 'bold',
  },
  emptyText: {
    textAlign: 'center',
    marginTop: 40,
    fontSize: 16,
    color: '#999',
  },
});

export default TodoApp;

Performance Optimization

1. Memoization

import React, { memo } from 'react';
import { Text, View } from 'react-native';

const UserCard = memo(({ user }) => {
  console.log('Rendering:', user.name);
  return (
    <View>
      <Text>{user.name}</Text>
    </View>
  );
});

export default UserCard;

2. useMemo & useCallback

import React, { useState, useMemo, useCallback } from 'react';
import { View, Button, Text } from 'react-native';

const OptimizedComponent = () => {
  const [count, setCount] = useState(0);
  const [items, setItems] = useState([1, 2, 3]);

  const expensiveValue = useMemo(() => {
    return items.reduce((sum, item) => sum + item, 0);
  }, [items]);

  const handlePress = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <View>
      <Text>Sum: {expensiveValue}</Text>
      <Button title="Increment" onPress={handlePress} />
    </View>
  );
};

export default OptimizedComponent;

3. FlatList Optimization

<FlatList
  data={largeList}
  renderItem={renderItem}
  keyExtractor={(item) => item.id.toString()}
  removeClippedSubviews={true}
  maxToRenderPerBatch={10}
  updateCellsBatchingPeriod={50}
  initialNumToRender={10}
/>

4. Image Optimization

import { Image } from 'react-native';

<Image
  source={{ uri: 'https://example.com/image.jpg' }}
  style={{ width: 200, height: 200 }}
  resizeMode="contain"
  defaultSource={require('./placeholder.png')}
/>

Deployment Process

iOS Deployment

# Build for production
cd ios
pod install
cd ..
npx react-native run-ios --configuration Release

# Archive for App Store
xcode-select --install
cd ios
xcodebuild -workspace MyAwesomeApp.xcworkspace \
  -scheme MyAwesomeApp \
  -configuration Release \
  -archivePath MyAwesomeApp.xcarchive \
  archive

Android Deployment

# Generate signing key
keytool -genkey -v -keystore my-release-key.keystore \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -alias my-key-alias

# Build APK
cd android
./gradlew bundleRelease

# Build AAB (recommended for Play Store)
./gradlew bundleRelease

Deployment Checklist

  • āœ… Update version numbers
  • āœ… Test on real devices
  • āœ… Optimize bundle size
  • āœ… Configure app icons and splash screens
  • āœ… Set up analytics and crash reporting
  • āœ… Prepare store listings and screenshots
  • āœ… Implement privacy policy

Pros & Cons

Advantages

BenefitDetails
Code ReusabilityShare 70-90% code between iOS and Android
Faster DevelopmentReduce time-to-market significantly
Hot ReloadInstant feedback during development
Large EcosystemThousands of libraries available
Cost EffectiveFewer developers needed
Strong CommunityExtensive documentation and support

Disadvantages

ChallengeDetails
PerformanceSlightly slower than native apps
Platform-Specific IssuesSome features require native code
Learning CurveRequires JavaScript and React knowledge
DebuggingCan be more complex than native development
App SizeLarger bundle size compared to native
Dependency UpdatesBreaking changes in libraries

Conclusion

React Native remains a powerful choice for cross-platform mobile development in 2026. By leveraging JavaScript and React, developers can build high-quality applications for both iOS and Android platforms efficiently.

Key Takeaways:

  • Start with Expo for rapid prototyping
  • Master navigation and state management
  • Optimize performance with memoization
  • Test thoroughly on real devices
  • Follow platform-specific guidelines

Next Steps:

  1. Build your first app using this guide
  2. Explore advanced libraries (Redux, Firebase, etc.)
  3. Join the React Native community
  4. Deploy to app stores
  5. Gather user feedback and iterate

The future of mobile development is cross-platform, and React Native is leading the way. Start building today!


Resources: