React Native is a framework created by Facebook that lets developers construct apps, for smartphones using JavaScript and React library. A favorite, among front end developers.This tool is commonly employed to make applications that function on both iOS and Android devices with one set of code simplifying cross platform app development.
React Native essentially allows developers to create apps using elements instead of web components, as the foundation. It harnesses the React component structure. Merges it with features specific to native platforms to give apps an authentic native appearance and operation. In contrast to applications that depend on WebView (such as Apache Cordova) React Native applications employ genuine native components, for enhanced efficiency and more seamless user interactions.
Key Features:
To get started with React Native, you have two main ways to set up your environment:
Option 1: Installing React Native Using Expo CLI
Expo is a great option if you want a quick and easy setup without worrying about configuring native code for iOS and Android. It’s ideal for beginners or developers focusing on JavaScript-only features.
Prerequisites
Step 1: Install Expo CLI
Open your terminal and run:
npm install -g expo-cli
You can also use yarn if it's your preferred package manager:
yarn global add expo-cli
Step 2: Create a New React Native Project
Now, create your first React Native project:
expo init MyFirstApp
You will be asked to select a template option (for example; Blank or Blank (TypeScript)).
Navigate into your project directory:
cd MyFirstApp
Step 3: Start the Development Server
Run the following command to start the app:
npm start
This will automatically launch a new tab in your browser with the Expo Dev Tools. You can then scan the QR code shown using the Expo Go app-available on both iOS and Android-or run your app on your physical device.
Alternatively, use:
npx expo start
Step 4: Running on a Device or Emulator
Android: If you have an Android emulator installed (like Android Studio), press a to launch it.
iOS: If you're on a Mac with Xcode installed, press i to open the iOS simulator.
Option 2: Installing React Native Using React Native CLI
Prerequisites
Step 1: Install the React Native CLI
First, install react-native globally:
npm install -g react-native
Step 2: Create a New React Native Project
In your terminal, run:
npx react-native init MyFirstApp
This will create a new project named MyFirstApp.
Step 3: Running the App
Navigate to your project folder:
cd MyFirstApp
To run the app on an Android emulator or a connected device:
npx react-native run-android
To run the app on the iOS simulator (macOS only):
npx react-native run-ios
Note: Please check your Android emulator or iOS simulator running before executing the above commands.
Step 4: Troubleshooting React Native
If you come across problems, with your setup or functionality is not working as expected in cases it is due, to either requirements or incorrect settings and setups. Refer to the official React Native documentation for troubleshooting steps: React Native Docs
Conclusion
Whether you use Expo or React Native CLI depends on your project's needs. Expo is great for rapid development, especially for beginners, while the React Native CLI provides full control and flexibility for more complex apps.
Components
Actually, components are the building blocks of your application in React Native. Components allow breaking up the UI into independent and reusable pieces, where each piece is considered in isolation. React Native supports two types of components:
Example: Functional Component
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
const Greeting = ({ name }) => (
<View style={styles.container}>
<Text style={styles.text}>Hello, {name}!</Text>
</View>
);
const App = () => (
<View>
<Greeting name="John" />
</View>
);
const styles = StyleSheet.create({
container: { padding: 20, backgroundColor: '#f0f8ff' },
text: { fontSize: 18, color: '#333' },
});
export default App;
React Native uses a CSS-like styling approach but relies on JavaScript objects. Styling can be done inline or using StyleSheet.
Example: Styling with StyleSheet
import { StyleSheet, View, Text } from 'react-native';
const App = () => (
<View style={styles.container}>
<Text style={styles.title}>Styled Component</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#4CAF50',
},
});
export default App;
Flexbox Layout
React Native uses Flexbox for layout, making it easy to create responsive designs.
<View style={(flex: 1. flexDirection: row', justifyContent: 'space-around' }}>
<View style={{ width: 50, height: 50, backgroundColor: 'red' }} />
<View style={{ width: 50, height: 50, backgroundColor: 'green'}} />
<View style=[{ width: 50, height: 50, backgroundColor: 'blue' />
</View>
To navigate between screens, React Native developers commonly use the React Navigation library.
Setting Up React Navigation
npm install @react-navigation/native @react-navigation/native-stack
npm install react-native-screens react-native-safe-area-context
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './HomeScreen';
import DetailsScreen from './DetailsScreen';
const Stack = createNativeStackNavigator();
const App = () => (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
export default App;
React Native leverages React hooks like useState and useReducer for managing component state. For global state, we can use Context API or libraries like Redux.
Local State with Hooks
import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increment" onPress={() => setCount(count + 1)} />
</View>
);
};
export default Counter;
Global State with Context API
import React, { useContext, useState } from 'react';
import { View, Button } from 'react-native';
const AppContext = React.createContext();
const AppProvider = ({ children }) => {
const [user, setUser] = useState(null);
return (
<AppContext.Provider value={{ user, setUser }}>
{children}
</AppContext.Provider>
);
};
const HomeScreen = () => {
const { user, setUser } = useContext(AppContext);
return (
<View>
<Button title="Login" onPress={() => setUser('John')} />
</View>
);
};
export { AppProvider, HomeScreen };
Redux for Complex State Management
npm install @reduxjs/toolkit react-redux
Fetching data is essential for most apps. React Native uses JavaScript's fetch API, but you can also use libraries like axios.
Fetching Data with Fetch API
import React, { useEffect, useState } from 'react';
import { View, Text, ActivityIndicator, FlatList } from 'react-native';
const App = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((json) => {
setData(json);
setLoading(false);
})
.catch((error) => {
console.error(error);
setLoading(false);
});
}, []);
return (
<View style={{ padding: 20 }}>
{loading ? (
<ActivityIndicator size="large" color="#0000ff" />
) : (
<FlatList
data={data}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item }) => <Text>{item.title}</Text>}
/>
)}
</View>
);
};
export default App;
Handling Errors
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
} catch (error) {
console.error('Error fetching data:', error);
}
Using Axios for Fetching Data
If you prefer using Axios:
npm install axios
React Native lets you use features of your device, such as the camera, GPS and file storage through built-in tools or third party libraries.
Accessing Device Features with Libraries
The react-native ecosystem includes many libraries to access native device features:
Camera: react-native-camera, react-native-vision-camera
Location: react-native-geolocation-service
File System: react-native-fs
Push Notifications: react-native-push-notification
Example 1: Accessing the Camera
For reaching the camera of the device, you can use the react-native-vision-camera package. This gives access to the camera that is modern and performant.
npm install react-native-vision-camera
On iOS, update the Info.plist:
<key>NSCameraUsage Description</key>
<string>We need your permission to use the camera</string>
<uses-permission android:name="android.permission.CAMERA"/>
import { Text, View, Button } from 'react-native';
import React, { useEffect, useState } from 'react';
import { Camera, useCameraDevices } from 'react-native-vision-camera';
const CameraScreen = () => {
const devices = useCameraDevices();
const device = devices.back;
useEffect(() => {
(async () => {
const status = await Camera.requestCameraPermission();
if (status !== 'authorized') alert('Camera permission required');
})();
}, []);
if (device == null) return <Text>Loading...</Text>;
return (
<Camera style={{ flex: 1 }} device={device} isActive={true} />
);
};
export default CameraScreen;
Example 2: Getting the User’s Location
Install the geolocation service:
npm install react-native-geolocation-service
Get user’s current location:
import React, { useEffect, useState } from 'react';
import { View, Text, Button, PermissionsAndroid } from 'react-native';
import Geolocation from 'react-native-geolocation-service';
const LocationExample = () => {
const [location, setLocation] = useState(null);
const requestPermission = async () => {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
};
const getLocation = async () => {
const hasPermission = await requestPermission();
if (hasPermission) {
Geolocation.getCurrentPosition(
(position) => setLocation(position.coords),
(error) => console.error(error),
{ enableHighAccuracy: true }
);
}
};
useEffect(() => {
getLocation();
}, []);
return location ? (
<Text>Latitude: {location.latitude}, Longitude: {location.longitude}</Text>
) : (
<Text>Fetching location...</Text>
);
};
export default LocationExample;
Ensuring your React Native app performs smoothly is crucial, especially on older devices. Here are some best practices to optimize performance:
Best Practices for Performance Optimization
Use FlatList for large lists instead of ScrollView.
Avoid unnecessary re-renders by using React.memo, useMemo, and useCallback.
Optimize images with libraries like react-native-fast-image.
Use shouldComponentUpdate in class components or React.memo for functional components to avoid unnecessary re-renders.
Enable Hermes (a JavaScript engine optimized for React Native) to reduce startup times.
Example: Optimizing FlatList with Memoization
import React, { memo } from 'react';
import { FlatList, Text, View } from 'react-native';
const Item = memo(({ item }) => {
console.log('Rendering item', item.id);
return <Text>{item.name}</Text>;
});
const App = () => {
const data = Array.from({ length: 1900 }, (_, index) => ({
id: index + 1,
name: `Item ${index + 1}`,
}));
return (
<FlatList
data={data}
renderItem={({ item }) => <Item item={item} />}
keyExtractor={(item) => item.id.toString()}
/>
);
};
export default App;
Animations make an app look smoothened and interactive. By using the Animated API or LayoutAnimation, or even a third-party library like react-native-reanimated, you are able to give your application life with fun interactivity.
Using the Animated API
import React, { useRef, useEffect } from 'react';
import { Animated, View } from 'react-native';
const FadeInView = () => {
const fadeAnim = useRef(new Animated.Value(0)).current;
useEffect(() => {
Animated.timing(fadeAnim, {
toValue: 1,
duration: 2000,
useNativeDriver: true,
}).start();
}, []);
return (
<Animated.View style={{ opacity: fadeAnim }}>
<View style={{ width: 200, height: 200, backgroundColor: 'skyblue' }} />
</Animated.View>
);
};
export default FadeInView;
Using react-native-reanimated
react-native-reanimated is a more performant option for complex animations.
npm install react-native-reanimated
Testing and debugging are essential to ensuring your app is reliable and bug-free.
Debugging Tools
React Native Debugger: A standalone tool that combines Redux DevTools with React DevTools.
Flipper: A desktop app that helps visualize and debug React Native apps.
Using console.log and Breakpoints
Add console.log statements to check variable values.
Use breakpoints in Visual Studio Code by clicking the gutter next to a line number.
Unit Testing with Jest
React Native apps commonly use Jest for unit testing.
npx jest --init
import React from 'react';
import renderer from 'react-test-renderer';
import App from '../App';
test('renders correctly', () => {
const tree = renderer.create(<App />).toJSON();
expect(tree).toMatchSnapshot();
});
End-to-End Testing with Detox
Detox is a powerful end-to-end testing tool for React Native.
npm install -g detox-cli
npm install detox
"detox": {
"testRunner": "jest",
"configurations": {
"ios": {
"device": {
"type": "iPhone 12"
},
"app": "ios/build/Build/Products/Debug-iphonesimulator/MyApp.app"
}
}
}
describe('App Tests', () => {
beforeAll(async () => {
await device.launchApp();
});
it('should show welcome screen', async () => {
await expect(element(by.id('welcome'))).toBeVisible();
});
});
Making your React Native application ready for end use is a very critical activity. However, publishing an app across iOS and Android differs. Let's break down how to publish your app on each so that people can download and use it.
iOS Deployment
To upload your iOS App to the App Store, you will need access to a Mac and an Apple Developer account.
Steps for iOS DeploymentGo to App Store Connect, create a new app record, and submit your build for review.
Create an App Store Connect Account:
Register as an Apple Developer at developer.apple.com.
Generate Certificates & Profiles:
Open Xcode. Now, go to Preferences > Accounts.
Create an iOS Distribution Certificate and Provisioning Profile.
Prepare Your App:
In your React Native project, open the ios folder using Xcode.
Update the Bundle Identifier to match your app’s identifier.
Set your Build Configuration to Release.
Archive and Distribute:
In Xcode, select Product > Archive.
Once archived, click Distribute App and follow the steps to upload to App Store Connect.
Submit for Review:
Go to App Store Connect, create a new app record, and submit your build for review.Archive and Distribute:
Making your React Native application ready for end use is a very critical activity. However, publishing an app across iOS and Android differs. Let's break down how to publish your app on each so that people can download and use it.
iOS Deployment
To upload your iOS App to the App Store, you will need access to a Mac and an Apple Developer account.
Steps for iOS DeploymentGo to App Store Connect, create a new app record, and submit your build for review.
Create an App Store Connect Account:
Register as an Apple Developer at developer.apple.com.
Generate Certificates & Profiles:
Open Xcode. Now, go to Preferences > Accounts.
Create an iOS Distribution Certificate and Provisioning Profile.
Prepare Your App:
In your React Native project, open the ios folder using Xcode.
Update the Bundle Identifier to match your app’s identifier.
Set your Build Configuration to Release.
Archive and Distribute:
In Xcode, select Product > Archive.
Once archived, click Distribute App and follow the steps to upload to App Store Connect.
Submit for Review:
Go to App Store Connect, create a new app record, and submit your build for review.Archive and Distribute:
Example Command to Build iOS App
cd ios
npx pod-install
xcodebuild -scheme "MyApp" -configuration Release archive -archivePath MyApp.xcarchive
Android Deployment
To deploy an Android app, you'll need to generate a signed APK or AAB (Android App Bundle).
Steps for Android Deployment
Generate a Keystore:
keytool -genkeypair -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key-alias
Update gradle.properties: Add the keystore details:
MYAPP_UPLOAD_STORE_FILE=my-release-key.jks
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=your-store-password
MYAPP_UPLOAD_KEY_PASSWORD=your-key-password
cd android
./gradlew clean
./gradlew assembleRelease
Create a new application on the Google Play Console.
Upload your app-release.aab file.
1. Organize Project Structure
Ensuring a well-structured project layout is essential to enhance the scalability and maintainability of your React Native app. Segmenting your codebase into logical modules, components, and screens is crucial. For instance, consider organizing your project in the following manner:
src
├── components/
│ ├── Button.js
│ ├── Header.js
├── screens/
│ ├── HomeScreen.js
│ ├── ProfileScreen.js
├── utils/
│ ├── api.js
├── App.js
This method will make development faster and help create apps more smoothly and efficiently.
Keeping things organized by separating different parts of your app is key. It helps developers focus on specific features without confusion or conflicts. This method boosts teamwork, speeds up development, and leads to better results.
2. Use Functional Component
Since the advent of React hooks, functional components have taken the lead as the preferred approach for writing components in React Native. Their readability, testability, and maintainability make them a standout choice.
Whenever possible, opt for functional components over class components, and leverage the potential of hooks like ‘useState’, ‘useEffect’, and ‘useContext’ to effectively manage state and handle side-effects in your application. This way, you can harness the true power of React Native development.
3. Optimise Images
When developing mobile apps, you must be aware of the image assets you include. If they are optimised, they can positively impact the app’s performance. To justify this, it’s recommended to use tools for compressing and resizing images before adding them to your project. Furthermore, React Native’s ‘Image’ component is an excellent resource for caching and efficiently loading images with various options.
4. Minimal use of Third-Party libraries
When developing an app, third-party libraries can help accelerate the process. However, using them in small quantities is essential to avoid bloating the app and causing conflicts or performance problems. Before including a library, it’s necessary to consider its relevance and make sure it’s being regularly maintained and updated. Additionally, keep an observant watch on the app’s bundle size to prevent any unnecessary extra weight caused by adding new libraries.
5. Memory Management
Managing memory efficiently is essential when using mobile devices due to limited resources. To prevent memory leaks, clean up event listeners, timers, and subscriptions when components unmount. To handle this, you can use the cleanup function in the ‘useEffect’ hook. Additionally, it’s essential to be conscious of large data sets in memory, so consider using pagination or lazy-loading techniques when dealing with extensive lists or images.
6. Optimise Performance for Flatlist
When displaying extensive data lists, ‘FlatList’ is the ideal component for efficient rendering. However, proper usage can result in good performance. To ensure that React identifies items accurately, it is vital to supply a distinctive ‘keyExtractor’ prop. To optimise the rendering process for lengthy lists, consider using the ‘getItemLayout’ prop or ‘initialNumToRender’.
7. Use React Native debugger
If you want to inspect and debug your app’s components and state, React Native Debugger is a powerful tool to use. It provides a top-notch development experience and can help you identify issues such as performance bottlenecks and state management problems.
8. Stay Updated
Keeping up-to-date with the frequent updates and improvements of React Native ensures optimal performance, security, and access to the latest features. These can be achieved by following the official documentation and community forums, attending conferences or webinars, and regularly upgrading your app to the newest version of React Native.