React Native: Building Cross-Platform Apps
Introduction
React Native allows you to build native mobile apps using JavaScript and React. Write once, deploy to both iOS and Android with shared codebase and native performance.
1. Setup and Installation
# Install React Native CLI
npm install -g react-native-cli
# Create new project
npx react-native init MyApp
# Run on iOS
cd MyApp
npx react-native run-ios
# Run on Android
npx react-native run-android
2. Core Components
import React from 'react';
import {
View,
Text,
Image,
ScrollView,
TextInput,
Button,
TouchableOpacity,
FlatList,
StyleSheet
} from 'react-native';
function App() {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello React Native</Text>
<Image
source={{uri: 'https://reactnative.dev/img/tiny_logo.png'}}
style={styles.logo}
/>
<TouchableOpacity style={styles.button}>
<Text>Press Me</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 16
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 16
},
logo: {
width: 100,
height: 100
},
button: {
backgroundColor: '#2196F3',
padding: 12,
borderRadius: 8
}
});
3. Navigation with React Navigation
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context
// App.js
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
// Navigation between screens
function HomeScreen({ navigation }) {
return (
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details', { itemId: 42 })}
/>
);
}
4. State Management
// Using Context API
import React, { createContext, useContext, useState } from 'react';
const AppContext = createContext();
export function AppProvider({ children }) {
const [user, setUser] = useState(null);
return (
<AppContext.Provider value={{ user, setUser }}>
{children}
</AppContext.Provider>
);
}
export const useApp = () => useContext(AppContext);
// Using Redux Toolkit
npm install @reduxjs/toolkit react-redux
import { createSlice, configureStore } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: { data: null },
reducers: {
setUser: (state, action) => {
state.data = action.payload;
}
}
});
const store = configureStore({
reducer: { user: userSlice.reducer }
});
5. API Calls and Data Fetching
import { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://api.example.com/users')
.then(res => res.json())
.then(data => {
setUsers(data);
setLoading(false);
})
.catch(error => console.error(error));
}, []);
if (loading) return <Text>Loading...</Text>;
return (
<FlatList
data={users}
keyExtractor={item => item.id.toString()}
renderItem={({item}) => (
<View style={styles.userItem}>
<Text>{item.name}</Text>
</View>
)}
/>
);
}
6. Styling
// StyleSheet
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff'
}
});
// Platform-specific styles
import { Platform } from 'react-native';
const styles = StyleSheet.create({
text: {
...Platform.select({
ios: { fontFamily: 'Arial' },
android: { fontFamily: 'Roboto' }
})
}
});
// Styled Components
npm install styled-components
import styled from 'styled-components/native';
const Container = styled.View`
flex: 1;
justify-content: center;
align-items: center;
background-color: ${props => props.theme.background};
`;
const Title = styled.Text`
font-size: 24px;
font-weight: bold;
color: ${props => props.theme.text};
`;
7. Native Modules
// Using community modules
npm install react-native-camera
npm install react-native-geolocation-service
npm install @react-native-async-storage/async-storage
// Camera example
import { RNCamera } from 'react-native-camera';
<RNCamera
style={styles.preview}
type={RNCamera.Constants.Type.back}
onBarCodeRead={handleBarCodeRead}
/>
// Storage example
import AsyncStorage from '@react-native-async-storage/async-storage';
await AsyncStorage.setItem('@user', JSON.stringify(userData));
const user = await AsyncStorage.getItem('@user');
8. Performance Optimization
// Use FlatList for long lists
<FlatList
data={items}
renderItem={({item}) => <Item data={item} />}
keyExtractor={item => item.id}
removeClippedSubviews={true}
maxToRenderPerBatch={10}
windowSize={10}
/>
// Memoize components
import React, { memo } from 'react';
const ExpensiveComponent = memo(({ data }) => {
return <View>{data}</View>;
});
// Use InteractionManager
import { InteractionManager } from 'react-native';
componentDidMount() {
InteractionManager.runAfterInteractions(() => {
// Long running task
});
}
9. Testing
// Jest testing
npm install --save-dev @testing-library/react-native
import { render, fireEvent } from '@testing-library/react-native';
test('button press', () => {
const { getByText } = render(<MyComponent />);
const button = getByText('Press Me');
fireEvent.press(button);
expect(getByText('Pressed!')).toBeTruthy();
});
10. Deployment
# iOS
cd ios
pod install
# Open Xcode and archive
# Android
cd android
./gradlew assembleRelease
# App signing
keytool -genkeypair -v -storetype PKCS12 -keystore my-release-key.keystore
💡 Best Practices:
- Use TypeScript for type safety
- Implement proper error boundaries
- Optimize images and assets
- Use Hermes engine for better performance
- Test on real devices
- Follow platform design guidelines
Conclusion
React Native enables efficient cross-platform mobile development with a single codebase. Master these patterns to build professional, performant mobile applications for iOS and Android.