Use the key prop to reset internal state
When the
React Native Hub
When the
key prop changes on an element, the render of this element is not interpreted as an update, but as an unmount plus a mount of a brand new component instance with a fresh state.function Layout({ currentItem }) {
/* When currentItem changes, we want any useState inside <EditForm/>
to be reset to a new initial value corresponding to the new item */
return (
<EditForm
item={currentItem}
key={currentItem.id}
/>
)
}React Native Hub
π1
π Implementing Expo Biometric Authentication
Biometric authentication (Face ID, Touch ID, fingerprint) enhances security and improves the user experience in mobile apps. With Expoβs LocalAuthentication API, integrating it into your React Native app is seamless. Hereβs how you can do it! π
1οΈβ£ Install the LocalAuthentication API
First, install the required package:
2οΈβ£ Check for Biometric Support
Before prompting authentication, check if the device supports biometrics:
3οΈβ£ Prompt for Authentication
Trigger authentication when the user tries to access a protected section:
4οΈβ£ Implement in a Component
Hereβs how you can put it all together in a button:
React Native Hub
Biometric authentication (Face ID, Touch ID, fingerprint) enhances security and improves the user experience in mobile apps. With Expoβs LocalAuthentication API, integrating it into your React Native app is seamless. Hereβs how you can do it! π
1οΈβ£ Install the LocalAuthentication API
First, install the required package:
npx expo install expo-local-authentication
2οΈβ£ Check for Biometric Support
Before prompting authentication, check if the device supports biometrics:
import * as LocalAuthentication from 'expo-local-authentication';
const checkBiometricSupport = async () => {
const isHardwareAvailable = await LocalAuthentication.hasHardwareAsync();
const supportedTypes = await LocalAuthentication.supportedAuthenticationTypesAsync();
console.log('Biometric Supported:', isHardwareAvailable);
console.log('Supported Types:', supportedTypes);
};
3οΈβ£ Prompt for Authentication
Trigger authentication when the user tries to access a protected section:
const authenticateUser = async () => {
const result = await LocalAuthentication.authenticateAsync({
promptMessage: 'Authenticate to continue',
fallbackLabel: 'Enter passcode',
});
if (result.success) {
console.log('Authentication Successful!');
} else {
console.log('Authentication Failed:', result.error);
}
};
4οΈβ£ Implement in a Component
Hereβs how you can put it all together in a button:
import React from 'react';
import { View, Button, Alert } from 'react-native';
import * as LocalAuthentication from 'expo-local-authentication';
const BiometricAuth = () => {
const handleAuth = async () => {
const result = await LocalAuthentication.authenticateAsync({
promptMessage: 'Authenticate with Biometrics',
});
Alert.alert(result.success ? 'Authenticated' : 'Failed', result.success ? 'Access Granted' : 'Access Denied');
};
return (
<View>
<Button title="Login with Biometrics" onPress={handleAuth} />
</View>
);
};
export default BiometricAuth;
React Native Hub
π3β‘1π₯1
π¨ Best Practices for Styling Mobile Apps
Styling plays a crucial role in building beautiful and maintainable React Native apps. Following best practices ensures consistency, better performance, and easier scalability. Here are some key takeaways:
β Use StyleSheet.create() β This optimizes performance by preventing unnecessary re-renders.
β Leverage Global Styles β Define common styles in a separate file to maintain consistency across the app.
β Use Theme-Based Styling β Implement dark mode and dynamic themes using context or state management.
β Avoid Inline Styles β Overusing inline styles leads to performance issues and redundant recalculations.
β Use Flexbox for Layouts β Flexbox provides a responsive and adaptive layout system.
β Styled Components β Reusable components for common UI elements.
By following these best practices, you can create visually appealing, efficient, and scalable React Native applications.
π Read more: Full Article Here
React Native Hub
Styling plays a crucial role in building beautiful and maintainable React Native apps. Following best practices ensures consistency, better performance, and easier scalability. Here are some key takeaways:
β Use StyleSheet.create() β This optimizes performance by preventing unnecessary re-renders.
β Leverage Global Styles β Define common styles in a separate file to maintain consistency across the app.
β Use Theme-Based Styling β Implement dark mode and dynamic themes using context or state management.
β Avoid Inline Styles β Overusing inline styles leads to performance issues and redundant recalculations.
β Use Flexbox for Layouts β Flexbox provides a responsive and adaptive layout system.
β Styled Components β Reusable components for common UI elements.
By following these best practices, you can create visually appealing, efficient, and scalable React Native applications.
π Read more: Full Article Here
React Native Hub
π― Discriminated Unions: Managing Complex State in React Native
Handling complex state can lead to unexpected bugs if not structured properly. Discriminated unions provide a powerful way to manage state transitions explicitly, ensuring type safety and preventing invalid states.
πΉ What Are Discriminated Unions?
A discriminated union is a TypeScript feature that allows defining multiple state variations with a common βdiscriminatorβ property.
π Example: Managing Fetch States
β Why Use Discriminated Unions?
- Ensures state transitions are explicit and well-defined
- Prevents invalid states (e.g., having both
- Improves type safety and reduces runtime errors
By structuring your state this way, your application logic remains predictable and easier to maintain! π
React Native Hub
Handling complex state can lead to unexpected bugs if not structured properly. Discriminated unions provide a powerful way to manage state transitions explicitly, ensuring type safety and preventing invalid states.
πΉ What Are Discriminated Unions?
A discriminated union is a TypeScript feature that allows defining multiple state variations with a common βdiscriminatorβ property.
π Example: Managing Fetch States
type FetchState =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: string[] }
| { status: 'error'; error: string };
const fetchReducer = (state: FetchState, action: any): FetchState => {
switch (action.type) {
case 'FETCH_START':
return { status: 'loading' };
case 'FETCH_SUCCESS':
return { status: 'success', data: action.payload };
case 'FETCH_ERROR':
return { status: 'error', error: action.payload };
default:
return state;
}
};
β Why Use Discriminated Unions?
- Ensures state transitions are explicit and well-defined
- Prevents invalid states (e.g., having both
data and `error`)- Improves type safety and reduces runtime errors
By structuring your state this way, your application logic remains predictable and easier to maintain! π
React Native Hub
πΉ Generics in React: Reusable & Flexible Components π
Generics in TypeScript allow you to build reusable and strongly-typed components that adapt to different data structures. This is especially useful for handling lists, forms, or APIs where the structure varies.
π Example: A Reusable Table Component
π₯ Why Use Generics?
β Type-Safe: Enforces correct data structures at compile-time
β Reusable: Works with any data type, reducing duplicate code
β Flexible: Keeps your components dynamic without sacrificing type safety
By leveraging generics, you can build components that adapt to various use cases while maintaining clean and maintainable code! π‘
React Native Hub
Generics in TypeScript allow you to build reusable and strongly-typed components that adapt to different data structures. This is especially useful for handling lists, forms, or APIs where the structure varies.
π Example: A Reusable Table Component
type TableProps<T> = {
data: T[];
renderRow: (item: T) => React.ReactNode;
};
function Table<T>({ data, renderRow }: TableProps<T>) {
return (
<table>
<tbody>{data.map((item, index) => <tr key={index}>{renderRow(item)}</tr>)}</tbody>
</table>
);
}
// Usage
type User = { id: number; name: string };
const users: User[] = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
<Tabledata={users}
renderRow={(user) => (
<>
<td>{user.id}</td>
<td>{user.name}</td>
</>
)}
/>;
π₯ Why Use Generics?
β Type-Safe: Enforces correct data structures at compile-time
β Reusable: Works with any data type, reducing duplicate code
β Flexible: Keeps your components dynamic without sacrificing type safety
By leveraging generics, you can build components that adapt to various use cases while maintaining clean and maintainable code! π‘
React Native Hub
π2
What Is Cursor AI?
Cursor AI is an intelligent code editor built on Visual Studio Code, enhanced with robust AI capabilities. It offers features like:
β Autocompletion: Context-aware code suggestions.
β Code Generation: Write components, functions, or tests with natural language prompts.
β Debugging Assistance: Identify errors and receive fixes in real time.
β Documentation Search: Instant access to React Native APIs and libraries.
For React Native developers, this means faster iteration, reduced boilerplate code, and fewer context switches between tools.
https://www.cursor.com/
React Native Hub
Cursor AI is an intelligent code editor built on Visual Studio Code, enhanced with robust AI capabilities. It offers features like:
β Autocompletion: Context-aware code suggestions.
β Code Generation: Write components, functions, or tests with natural language prompts.
β Debugging Assistance: Identify errors and receive fixes in real time.
β Documentation Search: Instant access to React Native APIs and libraries.
For React Native developers, this means faster iteration, reduced boilerplate code, and fewer context switches between tools.
https://www.cursor.com/
React Native Hub
π3
Mapped Types: Transforming Props and State
Mapped types in TypeScript allow you to create new types by transforming existing ones. This is particularly useful for defining derived states, props, or configurations in React Native applications.
πΉ Example: Partial Form Props
Let's say you have a form with fields like
β Why Itβs Useful:
πΉ Flexible Form Handling β Easily create types for form validation without duplicating fields.
πΉ Ensures Type Safety β Prevents typos and ensures every field has a corresponding error type.
πΉ Reusable & Scalable β Can be applied to API responses, configurations, and component props.
React Native Hub
Mapped types in TypeScript allow you to create new types by transforming existing ones. This is particularly useful for defining derived states, props, or configurations in React Native applications.
πΉ Example: Partial Form Props
Let's say you have a form with fields like
name, email, and age. You can use mapped types to define an error object that corresponds to each field dynamically:
type FormValues = {
name: string;
email: string;
age: number;
};
// Mapped Type for Errors
type FormErrors<T> = {
[K in keyof T]?: string;
};
const errors: FormErrors<FormValues> = {
name: "Name is required",
email: "Email is invalid",
};
β Why Itβs Useful:
πΉ Flexible Form Handling β Easily create types for form validation without duplicating fields.
πΉ Ensures Type Safety β Prevents typos and ensures every field has a corresponding error type.
πΉ Reusable & Scalable β Can be applied to API responses, configurations, and component props.
React Native Hub
My First Medium Article is Live! π
Hey everyone! I just published my first article on Medium about.
π Read it here: https://medium.com/@arsdev/how-i-increased-list-scroll-fps-from-30-to-58-in-react-native-34504f8d802c
If you find it useful, Iβd really appreciate your claps, comments, and sharesβthey help a lot!π
Thanks for your support! π
React Native Hub
Hey everyone! I just published my first article on Medium about.
π Read it here: https://medium.com/@arsdev/how-i-increased-list-scroll-fps-from-30-to-58-in-react-native-34504f8d802c
If you find it useful, Iβd really appreciate your claps, comments, and sharesβthey help a lot!π
Thanks for your support! π
React Native Hub
Please open Telegram to view this post
VIEW IN TELEGRAM
π4
From Solo to Duo: Transitioning to Pair Programming π₯
Working alone has its perks, but have you ever considered the power of pair programming? This article explores how switching from solo development to coding with a partner can boost productivity, improve code quality, and accelerate learning.
π Read article here
Have you tried pair programming? Share your thoughts in the comments! π¬
React Native Hub
Working alone has its perks, but have you ever considered the power of pair programming? This article explores how switching from solo development to coding with a partner can boost productivity, improve code quality, and accelerate learning.
π Read article here
Have you tried pair programming? Share your thoughts in the comments! π¬
React Native Hub
I've just published a new article
Check it out and let me know your thoughts! Your support means a lot. π
π Read here: Why Every React Native Developer Should Understand useCallback
React Native Hub
Check it out and let me know your thoughts! Your support means a lot. π
π Read here: Why Every React Native Developer Should Understand useCallback
React Native Hub
π₯2
π Master `useRef` for Better TextInput Handling in React Native
Struggling with managing input fields efficiently? Instead of relying on state updates that cause unnecessary re-renders,
Why Use `useRef` with TextInput?
β Avoid Unnecessary Re-renders β Since
β Easily Manage Focus β You can programmatically focus on an input field when needed.
β Access Input Methods Directly β Clear, blur, or manipulate text fields without updating state
Example Usage:
React Native Hub
Struggling with managing input fields efficiently? Instead of relying on state updates that cause unnecessary re-renders,
useRef lets you interact directly with TextInput methods.Why Use `useRef` with TextInput?
β Avoid Unnecessary Re-renders β Since
useRef doesnβt trigger component updates, itβs great for performance.β Easily Manage Focus β You can programmatically focus on an input field when needed.
β Access Input Methods Directly β Clear, blur, or manipulate text fields without updating state
Example Usage:
import React, { useRef, useState } from "react";
import { TextInput, Button, View } from "react-native";
const InputExample = () => {
const inputRef = useRef<TextInput>(null);
const focusInput = () => {
inputRef.current?.focus();
};
const clearInput = () => {
setValue("");
inputRef.current?.clear();
};
const handleSubmit = () => {
const inputValue = inputRef.current?.value || ''; // Get the current value
console.log(inputValue); // Log the value when the user submits
};
return (
<View>
<TextInput
ref={inputRef}
onChangeText={(e) => (inputRef.current.value = e)} // Store the value in the ref
placeholder="Enter text..."
style={{ borderBottomWidth: 1, padding: 8 }}
/>
<Button title="Focus" onPress={focusInput} />
<Button title="Clear" onPress={clearInput} />
<Button title="Submit" onPress={handleSubmit} />
</View>
);
};
export default InputExample;
React Native Hub
π3
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
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
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