Hooks
RNCopilot provides a set of global hooks for common tasks: safe area padding, network detection, screen dimensions, route protection, press animations, auth state, and persistent storage.
useBottomPadding
Returns a numeric padding value that accounts for the tab bar height and the device’s safe area bottom inset. Use this to prevent content from being hidden behind the tab bar.
Source: src/hooks/useBottomPadding.ts
import { useBottomPadding } from '@/hooks';
export function MyScreen() {
const bottomPadding = useBottomPadding();
return (
<ScrollView contentContainerStyle={{ paddingBottom: bottomPadding }}>
{/* content */}
</ScrollView>
);
}Returns: number — the total bottom padding in pixels (tab bar height + safe area inset, with extra padding on Android).
useNetworkStatus
Monitors network connectivity and shows native alerts when the device goes offline or comes back online. Call this once in a top-level component (e.g., root layout).
Source: src/hooks/useNetworkStatus.ts
import { useNetworkStatus } from '@/hooks';
export default function RootLayout() {
useNetworkStatus();
return <Slot />;
}Returns: void — this hook has no return value. It manages alerts internally.
This hook uses @react-native-community/netinfo to subscribe to connectivity changes. It tracks the previous offline state with a ref to avoid duplicate alerts.
useScreenDimensions
Returns the current screen dimensions, orientation, breakpoint, and whether the device is a tablet.
Source: src/hooks/useScreenDimensions.ts
import { useScreenDimensions } from '@/hooks';
export function MyComponent() {
const { width, height, isLandscape, isPortrait, breakpoint, isTablet } =
useScreenDimensions();
return (
<View style={{ flexDirection: isTablet ? 'row' : 'column' }}>
{/* responsive layout */}
</View>
);
}Returns:
| Property | Type | Description |
|---|---|---|
width | number | Current window width in pixels |
height | number | Current window height in pixels |
isPortrait | boolean | true when height >= width |
isLandscape | boolean | true when width > height |
breakpoint | 'sm' | 'md' | 'lg' | 'xl' | Current breakpoint name |
isTablet | boolean | true when width >= 768 |
Breakpoints:
| Name | Min Width |
|---|---|
sm | 0 |
md | 768 |
lg | 1024 |
xl | 1280 |
useProtectedRoute
Redirects users based on authentication state. Unauthenticated users are sent to the login screen; authenticated users in the auth group are sent to the main tabs.
Source: src/hooks/useProtectedRoute.ts
import { useProtectedRoute } from '@/hooks/useProtectedRoute';
export default function RootLayout() {
useProtectedRoute();
return <Slot />;
}Returns: void — this hook manages navigation internally via expo-router.
Behavior:
- If
isLoadingistrue, the hook does nothing (waits for auth initialization). - If there is no session and the user is not in the
(auth)route group, redirects to/(auth)/login. - If there is a session and the user is in the
(auth)route group, redirects to/(main)/(tabs).
useAnimatedPress
Returns a Reanimated-powered animated style and press handlers for creating press-to-shrink effects on interactive elements.
Source: src/hooks/useAnimatedPress.ts
import Animated from 'react-native-reanimated';
import { useAnimatedPress } from '@/hooks';
export function PressableCard({ onPress, children }: PressableCardProps) {
const { animatedStyle, onPressIn, onPressOut } = useAnimatedPress({
scale: 0.97,
duration: 100,
});
return (
<Animated.View style={[styles.card, animatedStyle]}>
<Pressable
onPress={onPress}
onPressIn={onPressIn}
onPressOut={onPressOut}
>
{children}
</Pressable>
</Animated.View>
);
}Options:
| Option | Type | Default | Description |
|---|---|---|---|
scale | number | 0.97 | Scale factor when pressed |
duration | number | 100 | Animation duration in ms |
Returns:
| Property | Type | Description |
|---|---|---|
animatedStyle | AnimatedStyle | Apply to an Animated.View |
pressed | SharedValue<boolean> | Current pressed state |
onPressIn | () => void | Attach to Pressable.onPressIn |
onPressOut | () => void | Attach to Pressable.onPressOut |
useAuthStore
The Zustand auth store hook. Not a custom hook file — it is the store itself, used with selectors.
Source: src/providers/auth/authStore.ts
import { useAuthStore } from '@/providers/auth/authStore';
// In a component -- always use selectors
const user = useAuthStore((s) => s.user);
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
const isLoading = useAuthStore((s) => s.isLoading);
const session = useAuthStore((s) => s.session);
// Outside React (e.g., in Axios interceptors)
const session = useAuthStore.getState().session;Always use selectors with useAuthStore. Never call useAuthStore() without a selector — it subscribes to the entire store and causes unnecessary re-renders.
useStorage
A reactive hook for reading and writing values to MMKV persistent storage. See the Storage Utilities page for full details.
import { useStorage } from '@/utils/storage';
import { STORAGE_KEYS } from '@/utils/storage';
const { value, setValue, removeValue, loading, error, refresh } =
useStorage<string>(STORAGE_KEYS.preferences.language, {
defaultValue: 'en',
});useStorageBoolean
A specialized version of useStorage for boolean values, with an added toggle function.
import { useStorageBoolean } from '@/utils/storage';
import { STORAGE_KEYS } from '@/utils/storage';
const { value, toggle, setValue, loading } =
useStorageBoolean(STORAGE_KEYS.preferences.notificationsEnabled, {
defaultValue: true,
});