Skip to Content

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:

PropertyTypeDescription
widthnumberCurrent window width in pixels
heightnumberCurrent window height in pixels
isPortraitbooleantrue when height >= width
isLandscapebooleantrue when width > height
breakpoint'sm' | 'md' | 'lg' | 'xl'Current breakpoint name
isTabletbooleantrue when width >= 768

Breakpoints:

NameMin Width
sm0
md768
lg1024
xl1280

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 isLoading is true, 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:

OptionTypeDefaultDescription
scalenumber0.97Scale factor when pressed
durationnumber100Animation duration in ms

Returns:

PropertyTypeDescription
animatedStyleAnimatedStyleApply to an Animated.View
pressedSharedValue<boolean>Current pressed state
onPressIn() => voidAttach to Pressable.onPressIn
onPressOut() => voidAttach 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, });
Last updated on