React Native - Complete Development Guide

Master cross-platform mobile development with React and JavaScript

What You'll Learn

Introduction to React Native

React Native is a popular open-source framework for building native mobile applications using React and JavaScript. Created by Meta (Facebook), it allows developers to use React's component-based architecture to build real native mobile applications for iOS and Android.

Key Facts

  • Created by: Meta (Facebook) - 2015
  • Language: JavaScript/TypeScript + React
  • Platforms: iOS, Android, (Web with React Native Web)
  • License: MIT License
  • Used by: Facebook, Instagram, Airbnb (previously), Discord, Shopify, Tesla

How React Native Works

Unlike hybrid frameworks that use WebView, React Native renders actual native components. JavaScript code communicates with native code through a bridge, providing near-native performance.

Key Advantage: "Learn once, write anywhere" - Use your React knowledge to build native mobile apps while maintaining platform-specific optimizations when needed.

Why Choose React Native?

Code Reusability

Share 70-90% of code between iOS and Android. Write platform-specific code only when necessary.

React Ecosystem

Leverage the massive React ecosystem with thousands of libraries, tools, and community resources.

Hot Reloading

See changes instantly without losing app state. Fast development cycle dramatically improves productivity.

Native Performance

Renders actual native components, not web views. JavaScript runs on a separate thread for smooth UI.

Large Community

Backed by Meta with massive community support, extensive documentation, and active development.

Developer Experience

Use familiar web development tools, debugging techniques, and workflows.

React Native vs. Alternatives

Feature React Native Flutter Native (Swift/Kotlin)
Language JavaScript/TypeScript Dart Swift/Kotlin
UI Components Native widgets Custom rendered Native widgets
Performance Near-native Near-native Native
Learning Curve Easy (if you know React) Moderate Steep
Community Very Large Growing Platform-specific
Code Sharing 70-90% 90%+ 0% (separate apps)

When to Use React Native

✅ React Native is Great For:
  • Teams with React/JavaScript expertise
  • MVPs and rapid prototyping
  • Apps with standard UI patterns
  • Cross-platform apps with shared codebase
  • Content-heavy applications
⚠️ Consider Alternatives When:
  • App requires heavy graphics/animations (games)
  • Need maximum performance for complex calculations
  • Extensive use of platform-specific features
  • Team has no JavaScript experience

React Native Architecture

The Three Threads

1. JavaScript Thread

Runs your JavaScript code and React logic. Handles business logic, state management, and API calls.

2. Native/UI Thread

Runs native code and handles UI rendering. Ensures smooth 60 FPS animations and gestures.

3. Shadow Thread

Calculates layout using Facebook's Yoga layout engine (Flexbox implementation).

The Bridge

The bridge is the communication layer between JavaScript and native code. It's asynchronous, serialized, and batched for efficiency.

JavaScript Thread         Bridge         Native Thread
      │                      │                  │
      │─── Button Press ────→│                  │
      │                      │─── Event ──────→│
      │                      │                  │
      │                      │←── UI Update ────│
      │←─── Render ─────────│                  │
New Architecture (Fabric & TurboModules): React Native is introducing a new architecture that removes the bridge for more efficient communication.

Development Setup

Prerequisites

Two Ways to Start

1. Expo CLI (Recommended for Beginners)

# Install Expo CLI
npm install -g expo-cli

# Create new project
expo init MyApp
cd MyApp

# Start development server
expo start

# Scan QR code with Expo Go app on your phone

Pros: Quick setup, easier development, no native code compilation needed

Cons: Limited to Expo's APIs, larger app size

2. React Native CLI (Full Control)

# Create new project
npx react-native init MyApp
cd MyApp

# Run on iOS (macOS only)
npx react-native run-ios

# Run on Android
npx react-native run-android

Pros: Full control, can use any native library, smaller app size

Cons: Requires native development setup, more complex configuration

Core Components

React Native provides a set of core components that map to native platform components.

Basic Components

import React from 'react';
import {
  View,
  Text,
  Image,
  ScrollView,
  TextInput,
  Button,
  TouchableOpacity,
} from 'react-native';

function App() {
  return (
    <View style={{flex: 1, padding: 20}}>
      {/* Text Display */}
      <Text style={{fontSize: 24, fontWeight: 'bold'}}>
        Hello React Native!
      </Text>

      {/* Image */}
      <Image
        source={{uri: 'https://reactnative.dev/img/tiny_logo.png'}}
        style={{width: 50, height: 50}}
      />

      {/* Text Input */}
      <TextInput
        placeholder="Type here..."
        style={{borderWidth: 1, padding: 10, marginTop: 10}}
      />

      {/* Button */}
      <Button title="Press Me" onPress={() => alert('Pressed!')} />

      {/* Custom Touchable */}
      <TouchableOpacity
        style={{backgroundColor: 'blue', padding: 15, marginTop: 10}}
        onPress={() => console.log('Tapped')}
      >
        <Text style={{color: 'white', textAlign: 'center'}}>
          Custom Button
        </Text>
      </TouchableOpacity>
    </View>
  );
}

List Components

FlatList (Efficient for Large Lists)

import {FlatList} from 'react-native';

const DATA = [
  {id: '1', title: 'First Item'},
  {id: '2', title: 'Second Item'},
  {id: '3', title: 'Third Item'},
];

function MyList() {
  const renderItem = ({item}) => (
    <View style={{padding: 20, borderBottomWidth: 1}}>
      <Text>{item.title}</Text>
    </View>
  );

  return (
    <FlatList
      data={DATA}
      renderItem={renderItem}
      keyExtractor={item => item.id}
    />
  );
}

SectionList (Grouped Lists)

import {SectionList} from 'react-native';

const DATA = [
  {
    title: 'Fruits',
    data: ['Apple', 'Banana', 'Orange'],
  },
  {
    title: 'Vegetables',
    data: ['Carrot', 'Cucumber', 'Tomato'],
  },
];

function MySectionList() {
  return (
    <SectionList
      sections={DATA}
      renderItem={({item}) => <Text>{item}</Text>}
      renderSectionHeader={({section}) => (
        <Text style={{fontWeight: 'bold'}}>{section.title}</Text>
      )}
      keyExtractor={(item, index) => item + index}
    />
  );
}

Styling in React Native

React Native uses a JavaScript-based styling system similar to CSS but with camelCase properties.

Basic Styling

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

function MyComponent() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Styled Text</Text>
      <Text style={[styles.text, styles.bold]}>Multiple Styles</Text>
    </View>
  );
}

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

Flexbox Layout

React Native uses Flexbox for layout, similar to CSS.

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',        // 'row' or 'column'
    justifyContent: 'center',    // 'flex-start', 'flex-end', 'center', 'space-between', 'space-around'
    alignItems: 'center',        // 'flex-start', 'flex-end', 'center', 'stretch'
    flexWrap: 'wrap',            // 'nowrap' or 'wrap'
  },
  box: {
    flex: 1,                     // Takes available space
    margin: 10,
    padding: 20,
  },
});

Platform-Specific Styles

import {Platform, StyleSheet} from 'react-native';

const styles = StyleSheet.create({
  container: {
    marginTop: Platform.OS === 'ios' ? 20 : 0,
    ...Platform.select({
      ios: {
        backgroundColor: 'red',
      },
      android: {
        backgroundColor: 'blue',
      },
    }),
  },
});

State Management

1. React Hooks (Built-in)

import React, {useState, useEffect} from 'react';

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

  useEffect(() => {
    console.log(`Count changed to ${count}`);
  }, [count]);

  return (
    <View>
      <Text>Count: {count}</Text>
      <Button title="Increment" onPress={() => setCount(count + 1)} />
    </View>
  );
}

2. Context API

import React, {createContext, useContext, useState} from 'react';

const ThemeContext = createContext();

function ThemeProvider({children}) {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={{theme, setTheme}}>
      {children}
    </ThemeContext.Provider>
  );
}

function ThemedComponent() {
  const {theme, setTheme} = useContext(ThemeContext);
  return (
    <View style={{backgroundColor: theme === 'light' ? 'white' : 'black'}}>
      <Button
        title="Toggle Theme"
        onPress={() => setTheme(theme === 'light' ? 'dark' : 'light')}
      />
    </View>
  );
}

3. Redux

Popular for complex state management in large applications.

4. Modern Alternatives

Networking & APIs

Fetch API

import React, {useState, useEffect} from 'react';

function DataFetcher() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(json => {
        setData(json);
        setLoading(false);
      })
      .catch(err => {
        setError(err.message);
        setLoading(false);
      });
  }, []);

  if (loading) return <Text>Loading...</Text>;
  if (error) return <Text>Error: {error}</Text>;

  return <Text>{JSON.stringify(data)}</Text>;
}

Axios (Recommended)

import axios from 'axios';

const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {'Authorization': 'Bearer TOKEN'},
});

async function fetchData() {
  try {
    const response = await api.get('/users');
    return response.data;
  } catch (error) {
    console.error('API Error:', error);
    throw error;
  }
}

// POST request
async function createUser(userData) {
  const response = await api.post('/users', userData);
  return response.data;
}

Native Modules

Access platform-specific APIs not available in React Native core.

Popular Native Modules

Example: Using AsyncStorage

import AsyncStorage from '@react-native-async-storage/async-storage';

// Store data
const storeData = async (key, value) => {
  try {
    await AsyncStorage.setItem(key, JSON.stringify(value));
  } catch (error) {
    console.error('Error storing data:', error);
  }
};

// Retrieve data
const getData = async (key) => {
  try {
    const value = await AsyncStorage.getItem(key);
    return value != null ? JSON.parse(value) : null;
  } catch (error) {
    console.error('Error retrieving data:', error);
  }
};

Performance Optimization

Best Practices

Performance Monitoring

// Enable performance monitor
// Shake device and select "Show Perf Monitor"

// Or programmatically
import {NativeModules} from 'react-native';
NativeModules.DevSettings.setIsDebuggingRemotely(false);

Testing

Unit Testing with Jest

import React from 'react';
import {render} from '@testing-library/react-native';
import MyComponent from './MyComponent';

describe('MyComponent', () => {
  it('renders correctly', () => {
    const {getByText} = render(<MyComponent />);
    expect(getByText('Hello')).toBeTruthy();
  });

  it('handles button press', () => {
    const {getByText} = render(<MyComponent />);
    const button = getByText('Press Me');
    fireEvent.press(button);
    // Assert expected behavior
  });
});

End-to-End Testing with Detox

describe('Login Flow', () => {
  beforeAll(async () => {
    await device.launchApp();
  });

  it('should login successfully', async () => {
    await element(by.id('email')).typeText('user@example.com');
    await element(by.id('password')).typeText('password123');
    await element(by.id('loginButton')).tap();
    await expect(element(by.text('Welcome'))).toBeVisible();
  });
});

Deployment

iOS Deployment

  1. Configure app in Xcode
  2. Set up code signing and provisioning profiles
  3. Archive the app
  4. Upload to App Store Connect
  5. Submit for review

Android Deployment

  1. Generate a signing key
  2. Configure gradle for release builds
  3. Build release APK/AAB
  4. Upload to Google Play Console
  5. Submit for review

Build Release APK

# Generate release bundle
cd android
./gradlew bundleRelease

# The AAB will be in:
# android/app/build/outputs/bundle/release/app-release.aab

Best Practices

Project Structure

src/
├── components/      # Reusable components
├── screens/         # Screen components
├── navigation/      # Navigation configuration
├── services/        # API calls, utilities
├── store/           # State management
├── assets/          # Images, fonts
├── styles/          # Global styles
└── utils/           # Helper functions

Code Quality

Pro Tip: Use React Native Debugger or Flipper for powerful debugging capabilities including Redux DevTools and network inspection.

Additional Resources

Official Resources

Learning Platforms

Community & Tools

Related Topics