Master cross-platform mobile development with React and JavaScript
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.
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.
Share 70-90% of code between iOS and Android. Write platform-specific code only when necessary.
Leverage the massive React ecosystem with thousands of libraries, tools, and community resources.
See changes instantly without losing app state. Fast development cycle dramatically improves productivity.
Renders actual native components, not web views. JavaScript runs on a separate thread for smooth UI.
Backed by Meta with massive community support, extensive documentation, and active development.
Use familiar web development tools, debugging techniques, and workflows.
| 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) |
Runs your JavaScript code and React logic. Handles business logic, state management, and API calls.
Runs native code and handles UI rendering. Ensures smooth 60 FPS animations and gestures.
Calculates layout using Facebook's Yoga layout engine (Flexbox implementation).
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 ─────────│ │
# 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
# 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
React Native provides a set of core components that map to native platform 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>
);
}
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}
/>
);
}
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}
/>
);
}
React Native uses a JavaScript-based styling system similar to CSS but with camelCase properties.
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',
},
});
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,
},
});
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',
},
}),
},
});
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>
);
}
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>
);
}
Popular for complex state management in large applications.
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>;
}
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;
}
Access platform-specific APIs not available in React Native core.
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);
}
};
FlatList instead of ScrollView for long listsshouldComponentUpdate or React.memouseCallback and useMemo hooks// Enable performance monitor
// Shake device and select "Show Perf Monitor"
// Or programmatically
import {NativeModules} from 'react-native';
NativeModules.DevSettings.setIsDebuggingRemotely(false);
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
});
});
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();
});
});
# Generate release bundle
cd android
./gradlew bundleRelease
# The AAB will be in:
# android/app/build/outputs/bundle/release/app-release.aab
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