React Native
| Created | |
|---|---|
| Type | Library |
| Language | Javascript |
| Last Edit |
Introduction
React Native Basic
What is it

Components

JSX components will be compiled to their native views, but not Javascript logic/code as its run as a uncompiled JavaScript thread hosted by react native.
Project Setup
Expo
Managed app development
npx create-expo-app@latest <project-name> Setup Dev Environment
Basics
Core Components

Styling
No CSS available for styling
Written in JS, based on CSS syntax → Only subset of properties supported.

Inline Styles
<Text style={{margin: 16, border: '1px solid'}}> Hello World </Text><Text style={{margin: 16, borderWidth: 1, borderColor: 'red'}}> Hello World </Text>StyleSheet Objects
import { StyleSheet} from "react-native";
export default function App() {
return (
<View style={styles.container}>
<Text>Hello World</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});Color

Layouts & Flexbox
Element spacing and positioning in a container.

View component is already a flexbox with default flexDirection as column
Properties
import { StyleSheet, Text, View } from "react-native";
export default function App() {
return (
<View style={styles.container}>
<View
style={{
backgroundColor: "red",
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Text>1</Text>
</View>
<View
style={{
backgroundColor: "blue",
flex: 2,
justifyContent: "center",
alignItems: "center",
}}
>
<Text>2</Text>
</View>
<View
style={{
backgroundColor: "green",
flex: 1,
justifyContent: "center",
alignItems: "center",
}}
>
<Text>3</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 50,
flexDirection: "row",
width: "100%",
height: 300,
alignItems: "stretch",
justifyContent: "center",
},
});Here the flex property inside the child view determines how much space the component will occupy out of available space in parent.
Navigation
Package
npm install @react-navigation/nativeExpo dependencies
npx expo install react-native-screens react-native-safe-area-contextUsage
import { NavigationContainer } from '@react-navigation/native';
<NavigationContainer><App/></NavigationContainer>Navigators
https://reactnavigation.org/docs/stack-navigator#
- Stack
- Native Stack
- Bottom Tabs
- Drawer
Native Stack Implementation
Wrap stack screen in container and pass required screen as prop to stack.screen
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="GettingStarted" component={GettingStarted} />
<Stack.Screen name="SignIn" component={SignIn} />
</Stack.Navigator>
</NavigationContainer>Out of the box, the top-most screen (i.e. the first child inside of <Stack.Navigator>) is used as the default/initial screen.
Or you can set default by:
<Stack.Navigator initialRouteName="SignIn">Navigate
OPTION 1
Screens set as component for stack.screen will have navigation prop set, which can be used to navigate w.r.t name of screen sett in stack.screen.
const GettingStarted = ({ navigation }) => {
const pressHandler = () => {
navigation.navigate('SignIn');
};
return (
<View style={styles.buttonContainer}>
<GSButton onPress={pressHandler} />
</View>
);
};OPTION 2
Use hook: useNavigation
import { useNavigation } from '@react-navigation/native';
const GSButton = () => {
const navigation = useNavigation();
const pressHandler = () => {
navigation.navigate('OTP_Get');
};
return (
<Button mode="contained" onPress={pressHandler}>
Get Started
</Button>
);
};Navigation Hook Options
navigation.setOptions({
title: condition ? 'Title A' : 'Title B',
})
navigation.goBack();| Method | Description |
navigate(name, params) | Navigate to a screen in the stack. You can pass parameters. |
goBack() | Go back to the previous screen. |
push(name, params) | Push a new route to the stack, even if it’s the same as the current one. |
replace(name, params) | Replace the current route with a new one. |
pop(count) | Go back by a certain number of screens. |
popToTop() | Go back to the first screen in the stack. |
reset(config) | Reset the navigation state. Useful for authentication flows. |
setParams(params) | Update the route's params. |
dispatch(action) | Send a custom navigation action. |
Nested Navigators
Stack & Bottom Tabs In One
✅ Option 1: Bottom Tabs as the main navigator, with each tab having its own Stack
// App.js or Navigation.js
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
// Example screens
import HomeScreen from './screens/HomeScreen';
import DetailsScreen from './screens/DetailsScreen';
import SettingsScreen from './screens/SettingsScreen';
// Stack for Home Tab
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
);
}
// Main Tab Navigator
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="HomeTab" component={ } />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
✅ Option 2: Stack as the main navigator, with Bottom Tabs inside one of the screens
function Tabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Main" component={Tabs} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Protected Navigation
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { checkPersistentData } from './app/store/auth/auth-methods';
//? Auth Screens
import GettingStartedScreen from './app/screens/Auth/GettingStartedScreen';
import OtpGetScreen from './app/screens/Auth/OtpGetScreen';
import OtpVerifyScreen from './app/screens/Auth/OtpVerifyScreen';
//? Protected Screens
import HomeScreen from './app/screens/Home/HomeScreen';
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const AuthStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="GettingStarted"
component={GettingStartedScreen}
// options={{
// headerShown: false,
// }}
/>
<Stack.Screen
name="OTP_Get"
component={OtpGetScreen}
// options={{
// headerShown: false,
// }}
/>
<Stack.Screen
name="OTP_Verify"
component={OtpVerifyScreen}
// options={{
// headerShown: false,
// }}
/>
</Stack.Navigator>
);
};
const ProtectedTabs = () => {
return (
<Tab.Navigator>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
title: 'Home',
}}
/>
<Tab.Screen
name="My_Courses"
component={HomeScreen}
options={{
title: 'My Courses',
}}
/>
<Tab.Screen
name="Profile"
component={HomeScreen}
options={{
title: 'Profile',
}}
/>
</Tab.Navigator>
);
};
const Navigation = () => {
const dispatch = useDispatch();
const auth = useSelector((state) => state.auth);
useEffect(() => {
dispatch(checkPersistentData());
}, []);
return <NavigationContainer>{auth.isLoggedIn ? <ProtectedTabs /> : <AuthStack />}</NavigationContainer>;
};
export default Navigation;
HTTP Requests
Loading Indicator
Loading Overlay
import {View, ActivityIndicator, StyleSheet} from 'react-native';
const LoadingOverlay = () => {
return (
<View style={styles.container}>
<ActivityIndicator size="large" color="white" />
</View>
);
}
export default LoadingOverlay;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 24,
backgroundColor: 'grey',
},
});