To build a scalable React Native app with Expo, it’s essential to structure your project cleanly, set up navigation, and manage shared state efficiently. This guide briefly covers how routing and context come together to form a solid application foundation.
- Project Structure: Organize code using a src folder with separate screens and contexts for better maintainability.
- Routing Setup: Implement navigation using a stack-based router to handle screen transitions smoothly.
- Global State: Use React Context to manage and share state across multiple screens without prop drilling.
Implementing Routing and Global Context
It involves configuring screen navigation and managing shared application state using routing and React Context.
Step 1: Set Up a New Expo Project
Start by creating a new Expo project using the Expo CLI:
expo init ExpoRouterContextAppFollow the prompts to set up your project.
Step 2: Install Necessary Dependencies
Navigate to your project directory and install the required dependencies:
cd ExpoRouterContextAppnpm install @react-navigation/native @react-navigation/stack react-native-gesture-handlerNote: Expo handles most native configuration automatically.
Step 3: Create a Basic Folder Structure
Inside your project directory, create a src folder. Within the src folder, create screens and contexts directories:
mkdir srccd srcmkdir screens contextsStep 4: Implement a Router Using React Navigation
Create a Router.js file inside the src directory and implement a basic stack navigator using React Navigation:
// src/Router.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './screens/HomeScreen';
import DetailScreen from './screens/DetailScreen';
const Stack = createStackNavigator();
const Router = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detail" component={DetailScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default Router;
Step 5: Set Up a Context Provider for Global State Management
Create a GlobalContext.js file inside the contexts directory to manage global state using React context:
// src/contexts/GlobalContext.js
import React, { createContext, useState } from 'react';
export const GlobalContext = createContext();
export const GlobalProvider = ({ children }) => {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount(count + 1);
};
const decrementCount = () => {
setCount(count - 1);
};
return (
<GlobalContext.Provider
value={{
count,
incrementCount,
decrementCount,
}}
>
{children}
</GlobalContext.Provider>
);
};
Step 6: Create Screens
Inside the screens directory, create HomeScreen.js and DetailScreen.js files with some basic content:
// src/screens/HomeScreen.js
import React, { useContext } from 'react';
import { View, Text, Button } from 'react-native';
import { GlobalContext } from '../contexts/GlobalContext';
const HomeScreen = ({ navigation }) => {
const { count, incrementCount } = useContext(GlobalContext);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Text>Count: {count}</Text>
<Button title="Increment" onPress={incrementCount} />
<Button
title="Go to Detail"
onPress={() => navigation.navigate('Detail')}
/>
</View>
);
};
export default HomeScreen;
// src/screens/DetailScreen.js
import React, { useContext } from 'react';
import { View, Text, Button } from 'react-native';
import { GlobalContext } from '../contexts/GlobalContext';
const DetailScreen = ({ navigation }) => {
const { count, decrementCount } = useContext(GlobalContext);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Detail Screen</Text>
<Text>Count: {count}</Text>
<Button title="Decrement" onPress={decrementCount} />
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
};
export default DetailScreen;
Step 7: Integrate Router and Context Provider in App.js
Finally, integrate the router and context provider in your App.js file:
// App.js
import React from 'react';
import Router from './src/Router';
import { GlobalProvider } from './src/contexts/GlobalContext';
const App = () => {
return (
<GlobalProvider>
<Router />
</GlobalProvider>
);
};
export default App;
Final Outcome
This setup results in a well-structured React Native application with smooth navigation, shared state management, and improved scalability.
- Expo handles the app lifecycle and environment.
- React Navigation manages screen transitions.
- Context API provides global state.
- Clean folder structure improves scalability and maintainability.