Ars Dev
1.98K subscribers
70 photos
7 videos
75 links
Hi, I’m Ars! Here I share practical insights on programming and AI πŸš€

To learn more JOIN my private community https://www.skool.com/ars-dev-hub-3159/about?ref=71f574f3ce3542eb976d068c3e133e1b

Contact: @ars_kylnyk
Download Telegram
Mobile Bridge: Making WebViews Feel Native

Shopify's engineering team shares how they’ve enhanced the WebView experience using Mobile Bridge 

πŸ” What’s Inside:

- How Shopify allows WebViews to access native features (like camera, auth, navigation)

- Ensuring seamless communication between JavaScript and native platforms

- Techniques to make hybrid apps feel fully native to users

Read here

React Native Hub
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 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 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
Liskov Substitution Principle (LSP)

πŸ‘‰ Read the Post in Telegraph

React Native Hub
Interface Segregation Principle (ISP)

πŸ‘‰ Read the Post in Telegraph

React Native Hub
πŸ‘2
IMPORTANT QUESTION πŸ˜…

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:


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 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
πŸ‘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
😎
Please open Telegram to view this post
VIEW IN TELEGRAM
⚑2πŸ”₯2πŸ‘1
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:


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
⚑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 @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 experience

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
πŸ”₯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.

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.


πŸ‘©β€πŸ’» React Native Hub
Please open Telegram to view this post
VIEW IN TELEGRAM
πŸ“„ Native vs React Native - Research Paper

πŸ‘‰ Read the article here


πŸ‘©β€πŸ’» React Native Hub
Please open Telegram to view this post
VIEW IN TELEGRAM
πŸ‘2
πŸš€ 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
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
Please open Telegram to view this post
VIEW IN TELEGRAM
πŸ‘4