Single Responsibility Principle (SRP)
β Definition: A component should have only one reason to change, meaning it should do one thing and do it well.
β In React: Break down large components into smaller, reusable pieces, each handling a single responsibility.
Not following SRP: In this example, the
Following SRP: Now, letβs refactor the code to adhere to the Single Responsibility Principle by breaking it into three separate components.
1. Custom Hook for Data Fetching (`useUserData`)
2. Loading and Error Handling Component (`UserInfo`)
3. Main Component (`UserProfile`)
React Native Hub
β Definition: A component should have only one reason to change, meaning it should do one thing and do it well.
β In React: Break down large components into smaller, reusable pieces, each handling a single responsibility.
Not following SRP: In this example, the
UserProfile component handles fetching data, managing state, and rendering the UIβall in one component.
// β BAD EXAMPLE - Violating SRP
import React, { useState, useEffect } from 'react';
const UserProfile = () => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUserData = async () => {
try {
const response = await fetch('https://api.example.com/user');
const data = await response.json();
setUser(data);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchUserData();
}, []);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
};
export default UserProfile;
Following SRP: Now, letβs refactor the code to adhere to the Single Responsibility Principle by breaking it into three separate components.
1. Custom Hook for Data Fetching (`useUserData`)
// β GOOD EXAMPLE - Following SRP
import { useState, useEffect } from 'react';
const useUserData = () => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUserData = async () => {
try {
const response = await fetch('https://api.example.com/user');
const data = await response.json();
setUser(data);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchUserData();
}, []);
return { user, loading, error };
};
export default useUserData;
2. Loading and Error Handling Component (`UserInfo`)
// β GOOD EXAMPLE - Following SRP
import React from 'react';
const UserInfo = ({ user, loading, error }) => {
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
</div>
);
};
export default UserInfo;
3. Main Component (`UserProfile`)
// β GOOD EXAMPLE - Following SRP
import React from 'react';
import useUserData from './useUserData';
import UserInfo from './UserInfo';
const UserProfile = () => {
const { user, loading, error } = useUserData();
return <UserInfo user={user} loading={loading} error={error} />;
};
export default UserProfile;
React Native Hub
π5
Open/Closed Principle (OCP)
β Definition: Software entities should be open for extension but closed for modification.
β In React: Use higher-order components (HOCs), render props, or composition to extend component behaviour without modifying the existing code.
Not following OCP: In this example, the
Every time we want to add a new button type, we need to modify the existing component by adding a new
Following OCP: Instead of modifying the
React Native Hub
β Definition: Software entities should be open for extension but closed for modification.
β In React: Use higher-order components (HOCs), render props, or composition to extend component behaviour without modifying the existing code.
Not following OCP: In this example, the
Button component has different styles based on the type prop. Every time a new button style is needed, we have to modify the existing Button component.
// β BAD EXAMPLE - Violating OCP
import React from 'react';
const Button = ({ type, label }) => {
let style = {};
if (type === 'primary') {
style = { backgroundColor: 'blue', color: 'white' };
} else if (type === 'secondary') {
style = { backgroundColor: 'gray', color: 'white' };
} else if (type === 'danger') {
style = { backgroundColor: 'red', color: 'white' };
}
return <button style={style}>{label}</button>;
};
export default Button;
Every time we want to add a new button type, we need to modify the existing component by adding a new
if or else if conditions, which violates OCP.Following OCP: Instead of modifying the
Button component for every new style, we can create a Higher-Order Component (HOC) that adds different styles based on the button type. This way, the Button component remains unchanged, and we can extend its behaviour by wrapping it with different HOCs.
// β GOOD EXAMPLE - Following OCP
import React from 'react';
// Base Button Component
const Button = ({ style, label }) => {
return <button style={style}>{label}</button>;
};
// HOC for Primary Button
const withPrimaryStyle = (WrappedComponent) => {
return (props) => {
const style = { backgroundColor: 'blue', color: 'white' };
return <WrappedComponent {...props} style={style} />;
};
};
// HOC for Secondary Button
const withSecondaryStyle = (WrappedComponent) => {
return (props) => {
const style = { backgroundColor: 'gray', color: 'white' };
return <WrappedComponent {...props} style={style} />;
};
};
// HOC for Danger Button
const withDangerStyle = (WrappedComponent) => {
return (props) => {
const style = { backgroundColor: 'red', color: 'white' };
return <WrappedComponent {...props} style={style} />;
};
};
// Use the HOCs
const PrimaryButton = withPrimaryStyle(Button);
const SecondaryButton = withSecondaryStyle(Button);
const DangerButton = withDangerStyle(Button);
const App = () => (
<div>
<PrimaryButton label="Primary Button" />
<SecondaryButton label="Secondary Button" />
<DangerButton label="Danger Button" />
</div>
);
export default App;
React Native Hub
π3
IMPORTANT QUESTION π
Which format do you prefer for posts with code examplesβ
Which format do you prefer for posts with code examples
Anonymous Poll
79%
Like a regular post
21%
In a separate Telegraph article
Building a scalable React Native app requires a well-structured codebase, modular design, and best practices. This example show how to set up folder structure for Expo Router-based project with Zustand for state management, Axios for API handling, and Maestro for E2E testing. This structure ensures maintainability, scalability, and better developer experience.
Project Structure π
Hereβs a well-organized structure for your Expo React Native project:
React Native Hub
Project Structure π
Hereβs a well-organized structure for your Expo React Native project:
AwesomeProject/
βββ app/ # Expo Router Pages (Screens Only)
β βββ index.tsx # Home screen (β/β)
β βββ _layout.tsx # Global layout
β βββ auth/
β β βββ index.tsx # β/authβ (Auth entry point)
β β βββ login.tsx # β/auth/loginβ
β β βββ signup.tsx # β/auth/signupβ
β βββ chat/
β β βββ index.tsx # β/chatβ (Chat List)
β β βββ conversation.tsx # β/chat/conversationβ
β βββ settings/
β β βββ index.tsx # β/settingsβ
β β βββ notifications.tsx # β/settings/notificationsβ
β β βββ security.tsx # β/settings/securityβ
β βββ profile/
β β βββ index.tsx # β/profileβ
β β βββ edit.tsx # β/profile/editβ
β β βββ preferences.tsx # β/profile/preferencesβ
β
βββ modules/ # Feature Modules
β βββ auth/
β β βββ components/
β β β βββ LoginForm.tsx
β β β βββ SignupForm.tsx
β β βββ hooks/
β β β βββ useAuth.ts
β β βββ services/
β β β βββ authService.ts
β β βββ store/
β β β βββ useAuthStore.ts
β β βββ validation/
β β β βββ authSchema.ts
β
β βββ chat/
β β βββ components/
β β β βββ MessageBubble.tsx
β β β βββ ChatInput.tsx
β β βββ hooks/
β β β βββ useChat.ts
β β βββ services/
β β β βββ chatService.ts
β β βββ store/
β β β βββ useChatStore.ts
β β βββ utils/
β β β βββ chatHelpers.ts # Helper functions for chat
β
β βββ settings/
β β βββ components/
β β β βββ NotificationToggle.tsx
β β β βββ SecuritySettings.tsx
β β βββ store/
β β β βββ useSettingsStore.ts
β
β βββ profile/
β β βββ components/
β β β βββ AvatarUpload.tsx
β β β βββ ProfileForm.tsx
β β βββ hooks/
β β β βββ useProfile.ts
β β βββ services/
β β β βββ profileService.ts
β β βββ store/
β β β βββ useProfileStore.ts
β
βββ components/ # Global Reusable Components
β βββ Button.tsx
β βββ Input.tsx
β βββ Avatar.tsx
β βββ Modal.tsx # Custom modal component
β βββ Loader.tsx # Loader animation
β
βββ hooks/ # Global Hooks
β βββ useTheme.ts
β βββ useNetwork.ts
β βββ useNotifications.ts # Handle push notifications
β
βββ store/ # Global Zustand Stores
β βββ useThemeStore.ts
β βββ useUserStore.ts
β
βββ services/ # Global API Services
β βββ apiClient.ts # Axios Setup
β βββ notificationService.ts
β βββ uploadService.ts # File/Image Upload Service
β
βββ utils/ # Utility Functions
β βββ formatDate.ts
β βββ validateEmail.ts
β βββ navigation.ts
β βββ fileHelpers.ts # Helper functions for file handling
β
βββ localization/ # Multi-Language Support
β βββ en.json
β βββ es.json
β βββ index.ts
β
βββ env/ # Environment-Based Configurations
β βββ .env.development
β βββ .env.production
β βββ .env.staging
β
βββ __tests__/ # Tests
β βββ e2e/
β βββ unit/
β βββ jest.setup.ts
β
βββ .husky/ # Git Hooks
βββ tailwind.config.js # Tailwind Configuration
βββ app.config.ts # Expo Configuration
βββ tsconfig.json # TypeScript Configuration
βββ package.json # Dependencies
βββ README.md # Documentation
React Native Hub
π₯8π3
useLocalStorage β Persist Data Like a Pro in React Native
Ever needed to store user preferences or tokens in your React Native app?Instead of manually interacting with
β Implementation using
π§ͺ Usage Example: Theme Toggle
React Native Hub | #customhooks
Ever needed to store user preferences or tokens in your React Native app?Instead of manually interacting with
AsyncStorage, use this custom hook to simplify the process and write cleaner code.β Implementation using
@react-native-async-storage/async-storage:
import { useState, useEffect } from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";
function useAsyncStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(initialValue);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const loadValue = async () => {
try {
const item = await AsyncStorage.getItem(key);
setStoredValue(item != null ? JSON.parse(item) : initialValue);
} catch (error) {
console.error("Error loading from AsyncStorage", error);
} finally {
setIsLoading(false);
}
};
loadValue();
}, [key]);
const setValue = async (value) => {
try {
const valueToStore =
value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
await AsyncStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error("Error setting AsyncStorage", error);
}
};
return [storedValue, setValue, isLoading];
}
export default useAsyncStorage;
π§ͺ Usage Example: Theme Toggle
import React, { useEffect } from "react";
import { View, Text, Button, StyleSheet } from "react-native";
import useAsyncStorage from "./useAsyncStorage";
const ThemeSwitcher = () => {
const [theme, setTheme] = useAsyncStorage("theme", "light");
const toggleTheme = () => {
setTheme((prev) => (prev === "light" ? "dark" : "light"));
};
return (
<View style={[
styles.container,
theme === "dark" ? styles.dark : styles.light,
]}
>
<Text style={styles.text}>Current Theme: {theme}</Text>
<Button title="Toggle Theme" onPress={toggleTheme} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
dark: {
backgroundColor: "#222",
},
light: {
backgroundColor: "#fff",
},
text: {
fontSize: 20,
marginBottom: 16,
},
});
export default ThemeSwitcher;
React Native Hub | #customhooks
π4
App.js Conf 2025 has officially started! ππ
Hereβs todayβs lineup:
β Intro by Marcin Skotniczny
β Keynote by Charlie Cheever and Jon Samp
β Deploy Everywhere with Expo Router by Evan Bacon
β Expo on Orbit by Aaron Grider
β Life After Legacy: The New Architecture Future by Nico Corti and Riccardo Cipolleschi
β Legend List: Optimizing for Peak List Performance by Jay Meistrich
β Mozart Never Had React Native: You Do by Kim Chouard
β Radon IDE β Code with Glee by Krzysztof Magiera
β WebGPU β High performant 3D animations in React Native by Krzysztof Piaskowy
β Scaling Enterprise CI/CD: A Migration Success Story by Michael Blanchard
β Taking the Party Outside the App with App Clip and Live Activity by Alex Chou
β The Bigger Picture by Anisha Malde and Εukasz ChludziΕski
β Running Small Language Models on Your Phone: Bringing AI to Mobile with React Native and ExecuTorch by Mateusz KopciΕski
β Building React Native Apps with Premium Feel and Quality UX by SaΓΊl Sharma
Link to the stream: https://www.youtube.com/live/K2JTTKpptGs?si=A4_g8DHiouDmrWk6
React Native Hub
Hereβs todayβs lineup:
β Intro by Marcin Skotniczny
β Keynote by Charlie Cheever and Jon Samp
β Deploy Everywhere with Expo Router by Evan Bacon
β Expo on Orbit by Aaron Grider
β Life After Legacy: The New Architecture Future by Nico Corti and Riccardo Cipolleschi
β Legend List: Optimizing for Peak List Performance by Jay Meistrich
β Mozart Never Had React Native: You Do by Kim Chouard
β Radon IDE β Code with Glee by Krzysztof Magiera
β WebGPU β High performant 3D animations in React Native by Krzysztof Piaskowy
β Scaling Enterprise CI/CD: A Migration Success Story by Michael Blanchard
β Taking the Party Outside the App with App Clip and Live Activity by Alex Chou
β The Bigger Picture by Anisha Malde and Εukasz ChludziΕski
β Running Small Language Models on Your Phone: Bringing AI to Mobile with React Native and ExecuTorch by Mateusz KopciΕski
β Building React Native Apps with Premium Feel and Quality UX by SaΓΊl Sharma
Link to the stream: https://www.youtube.com/live/K2JTTKpptGs?si=A4_g8DHiouDmrWk6
React Native Hub
π2
Back for day two of App.js Conf. π¨βπ»β¨
Hereβs whatβs on the agenda today:
β Large-Scale React Native Development in the Age of AI by Rafael Mendiola
β Brownfield React Native at Scale: Ship Dozens of Micro-Apps Daily by Sojin Park
β Embracing Native Code and Capabilities in Your Expo App by Keith Kurak
β Towards a Stable JavaScript API by Alex Hunt
β Le Chat and a Brief History of Streaming by Delphine Bugner
β Everybody Can Cook with React Native by Enzo Manuel Mangano
β TanStack Query in Expo Apps: Improving DX and UX Like No Other by Devlin Duldulao
β Let's Go Live: React Native Live Streaming With Zero WebRTC Knowledge by MiΕosz Filimowski
β Building Secure React Native Apps by Jacob Arvidsson
β The Future of Authentication in React Native by Laura Beatris
β Software Composing: Expo Development for Your PM by Tomasz SuΕkowski
β Keyboard Management Evolution in React Native by Kiryl Ziusko
β Unlocking Revenue: Monetizing Your React Native App with In-App Purchases by Perttu LΓ€hteenlahti
Link to the stream: https://www.youtube.com/live/UTaJlqhTk2g?si=HZF4wIO4DmglErd9
React Native Hub
Hereβs whatβs on the agenda today:
β Large-Scale React Native Development in the Age of AI by Rafael Mendiola
β Brownfield React Native at Scale: Ship Dozens of Micro-Apps Daily by Sojin Park
β Embracing Native Code and Capabilities in Your Expo App by Keith Kurak
β Towards a Stable JavaScript API by Alex Hunt
β Le Chat and a Brief History of Streaming by Delphine Bugner
β Everybody Can Cook with React Native by Enzo Manuel Mangano
β TanStack Query in Expo Apps: Improving DX and UX Like No Other by Devlin Duldulao
β Let's Go Live: React Native Live Streaming With Zero WebRTC Knowledge by MiΕosz Filimowski
β Building Secure React Native Apps by Jacob Arvidsson
β The Future of Authentication in React Native by Laura Beatris
β Software Composing: Expo Development for Your PM by Tomasz SuΕkowski
β Keyboard Management Evolution in React Native by Kiryl Ziusko
β Unlocking Revenue: Monetizing Your React Native App with In-App Purchases by Perttu LΓ€hteenlahti
Link to the stream: https://www.youtube.com/live/UTaJlqhTk2g?si=HZF4wIO4DmglErd9
React Native Hub
useDebounce β Stop Unnecessary API Calls β³
When handling search inputs or live updates, debouncing prevents excessive API requests by delaying execution until the user stops typing.
Implementation:
Usage Example:
β Why Use It?
- Reduces unnecessary API calls
- Improves performance in search fields
- Ensures a smooth user experience
React Native Hub | #customhooks
When handling search inputs or live updates, debouncing prevents excessive API requests by delaying execution until the user stops typing.
Implementation:
import { useState, useEffect } from "react";
function useDebounce(value, delay = 500) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
export default useDebounce;
Usage Example:
const [searchTerm, setSearchTerm] = useState("");
const debouncedSearch = useDebounce(searchTerm, 300);
useEffect(() => {
if (debouncedSearch) {
fetch(`https://api.example.com/search?q=${debouncedSearch}`)
.then((res) => res.json())
.then((data) => console.log(data));
}
}, [debouncedSearch]);
<TextInput
placeholder="Search..."
onChangeText={(text) => setSearchTerm(text)}
/>;
β Why Use It?
- Reduces unnecessary API calls
- Improves performance in search fields
- Ensures a smooth user experience
React Native Hub | #customhooks
π7π1
π React Native 0.80 is out! Key updates you should know:
- Upgrades to React 19.1.0 for improved stability and bug fixes
- Introduces a new Strict TypeScript API (opt-in) with enhanced typings and reduced breaking changes
- Freezes the Legacy Architecture, paving the way for better future performanceβwatch for compatibility warnings
- iOS builds faster (up to ~12% improvement) with experimental prebuilt dependencies
- Android APK size drops (~1 MB) thanks to Interprocedural Optimization (IPO)
- The New App screen is now modular and visually refreshed
- Last RN version with bundled JavaScriptCore (JSC) β future releases will require community JSC
Read the full article here
React Native Hub
- Upgrades to React 19.1.0 for improved stability and bug fixes
- Introduces a new Strict TypeScript API (opt-in) with enhanced typings and reduced breaking changes
- Freezes the Legacy Architecture, paving the way for better future performanceβwatch for compatibility warnings
- iOS builds faster (up to ~12% improvement) with experimental prebuilt dependencies
- Android APK size drops (~1 MB) thanks to Interprocedural Optimization (IPO)
- The New App screen is now modular and visually refreshed
- Last RN version with bundled JavaScriptCore (JSC) β future releases will require community JSC
Read the full article here
React Native Hub
β‘5π3π1
π Full-Screen Image Viewer in Expo Made Easy
Andrew Chester shows how to implement a sleek, full-screen image viewer with zoom using Expo and the
Key Highlights:
- Install
- Wrap your image in
- Build a reusable overlay using
Perfect for apps where users need to inspect image detailsβjust like Instagram or Facebook.
https://medium.com/@andrew.chester/react-native-expo-full-screen-image-viewer-with-zoom-made-simple-d374081acc6d
React Native Hub
Andrew Chester shows how to implement a sleek, full-screen image viewer with zoom using Expo and the
@likashefqet/react-native-image-zoom library.Key Highlights:
- Install
@likashefqet/react-native-image-zoom + react-native-reanimated + gesture-handler- Wrap your image in
<Zoomable> to enable pinch & double-tap zoom- Build a reusable overlay using
ImageProvider + ImageView + useImperativeHandle for a smooth full-screen experiencePerfect for apps where users need to inspect image detailsβjust like Instagram or Facebook.
https://medium.com/@andrew.chester/react-native-expo-full-screen-image-viewer-with-zoom-made-simple-d374081acc6d
React Native Hub
π₯6
React vs Angular vs Vue
An eternal debate. I decided to ask Ai.
According to o3-pro, here are the key takeaways:
TL;DR β The 2025 Landscape
β React is confidently #1 in both installations and job openings,
β Angular is experiencing a corporate revival after the v17βv18 releases,
β Vue steadily holds its βpleasant and fastβ niche with high community loyalty.
Forecast for 2025β2027
π©βπ» React will remain the de facto standard. The release of React 19 with optimized server streaming will reinforce its leadership.
π©βπ» Angular will grow in the B2B niche thanks to Signals, but its strict TypeScript-first architecture means a high entry barrier.
π©βπ» Vue will continue to be a community favorite, especially in Asia. Itβll retain around 15β17% market share, but is unlikely to surpass Angular in job demand without a strong enterprise push.
π©βπ» React Native Hub
An eternal debate. I decided to ask Ai.
According to o3-pro, here are the key takeaways:
TL;DR β The 2025 Landscape
β React is confidently #1 in both installations and job openings,
β Angular is experiencing a corporate revival after the v17βv18 releases,
β Vue steadily holds its βpleasant and fastβ niche with high community loyalty.
Forecast for 2025β2027
On a global scale, React is objectively βbetterβ by the numbers,
but βbetter for your projectβ β depends on your teamβs needs, deadlines, regulations, and technical debt.
Please open Telegram to view this post
VIEW IN TELEGRAM
π The Future of React Native β What to Expect in 2025
React Native is evolving fast β and 2025 is shaping up to be a game-changer.
This article highlights key trends and innovations to watch:
- Tighter integration with AI and edge computing
- Growth of Expo and server-driven UI
- Better dev tools, faster builds, and more stable releases
π The Future of React Native in 2025
π©βπ» React Native Hub
React Native is evolving fast β and 2025 is shaping up to be a game-changer.
This article highlights key trends and innovations to watch:
- Tighter integration with AI and edge computing
- Growth of Expo and server-driven UI
- Better dev tools, faster builds, and more stable releases
π The Future of React Native in 2025
Please open Telegram to view this post
VIEW IN TELEGRAM
π3
π° How to Monetize a React Native App in 2025
Building apps is great. But turning them into income? Even better.
Here are the top monetization strategies for React Native devs:
π± In-App Purchases
Great for digital goods, subscriptions, or unlocking features.
π Ads (with control!)
Use platforms like AdMob or Facebook Audience Network β just donβt ruin the UX.
π Freemium Model
Offer a free version, upsell the premium with real value.
π Affiliate & Dropshipping
Integrate products/services and earn per conversion. Especially powerful for niche audiences.
π§βπ» SaaS & B2B Tools
Monetize with subscriptions, dashboards, or API-based solutions built on React Native
π©βπ» React Native Hub
Building apps is great. But turning them into income? Even better.
Here are the top monetization strategies for React Native devs:
π± In-App Purchases
Great for digital goods, subscriptions, or unlocking features.
π Ads (with control!)
Use platforms like AdMob or Facebook Audience Network β just donβt ruin the UX.
π Freemium Model
Offer a free version, upsell the premium with real value.
π Affiliate & Dropshipping
Integrate products/services and earn per conversion. Especially powerful for niche audiences.
π§βπ» SaaS & B2B Tools
Monetize with subscriptions, dashboards, or API-based solutions built on React Native
Please open Telegram to view this post
VIEW IN TELEGRAM
π4