Custom Hooks
Relevant source files
The following files were used as context for generating this wiki page:
Custom hooks in the eefashiondesign project are reusable functions that encapsulate component logic into a single, manageable unit. They follow the React hook conventions (starting with use) and allow for sharing stateful logic, side effects, and interactions with device or backend APIs without adding complexity to the component tree. This approach promotes cleaner, more readable, and easily testable components.
The project defines a collection of general-purpose utility hooks in src/hooks/index.js and proposes a more feature-specific, state-driven hook architecture within src/core/state/hooks/ for handling concerns like authentication and data synchronization. These hooks are fundamental to the application's architecture, providing abstractions for everything from animation and form management to network status and persistent storage.
Sources: src/hooks/index.js, TASK_4_DISCUSSION.md
General-Purpose Hooks
A suite of general-purpose hooks is available in src/hooks/index.js. These hooks provide solutions for common application-level problems, such as managing device APIs, handling user input, and controlling component state.
Sources: src/hooks/index.js
Summary of Hooks
| Hook | Description | Returns |
|---|---|---|
useKeyboard | Tracks the visibility of the on-screen keyboard. | isKeyboardVisible (boolean) |
useBackHandler | Executes a custom handler when the Android back button is pressed. | void |
useDebounce | Debounces a value, updating it only after a specified delay. | debouncedValue |
useThrottle | Throttles a value, updating it at most once per specified limit. | throttledValue |
useNetworkStatus | Tracks the device's network connection status and type. | { isConnected, connectionType } |
useAppState | Tracks the application's state (active, background, inactive). | appState (string) |
useAsyncStorage | Manages a state value persisted in AsyncStorage. | [storedValue, setValue, removeValue, loading] |
usePrevious | Returns the previous value of a state or prop. | previousValue |
useToggle | Manages a boolean state with a toggle function. | [value, toggle, setValue] |
useCountdown | Implements a countdown timer. | { seconds, isRunning, start, pause, reset } |
useInterval | A declarative setInterval hook. | void |
useTimeout | A declarative setTimeout hook. | void |
useForm | Manages form state, validation, and submission. | { values, errors, touched, handleChange, handleBlur, handleSubmit, ... } |
usePagination | Calculates pagination logic for a list of items. | { currentItems, currentPage, totalPages, nextPage, prevPage, ... } |
useArray | Provides helper functions for manipulating an array state. | { array, setArray, push, filter, update, remove, clear } |
Sources: src/hooks/index.js
useAsyncStorage
This hook abstracts the logic for reading from and writing to React Native's AsyncStorage. It provides a stateful value, functions to update or remove it, and a loading state.
The diagram below illustrates the flow for setting a value with useAsyncStorage.
Sources: src/hooks/index.js:101-131
useForm
The useForm hook is a comprehensive solution for managing form state, including values, touched states, and validation errors.
The following diagram shows the data flow during form submission.
Sources: src/hooks/index.js:237-285
State Management Hooks
The project architecture proposes a set of hooks in src/core/state/hooks/ that interface with Zustand stores to manage application-wide state. This creates a clean separation between UI components and state logic.
Sources: TASK_4_DISCUSSION.md, TASK_4_SUMMARY.md
useAuth
The useAuth hook is the primary interface for all authentication-related actions. It connects to the authStore (a Zustand store) and provides components with the user's authentication status and methods to perform auth operations like sign-in, sign-up, and sign-out.
Sources: TASK_4_SUMMARY.md
useAuth Interaction Flow
This sequence diagram shows how a component uses the useAuth hook to sign in a user.
This flow is based on the proposed architecture for the authentication system.
Sources: TASK_4_SUMMARY.md, TASK_4_DISCUSSION.md
useAuth Return Values
| Key | Type | Description |
|---|---|---|
user | object | The authenticated user object from Supabase. |
session | object | The current session object, including the access token. |
isAuthenticated | boolean | True if the user is currently authenticated. |
isLoading | boolean | True during an active authentication operation. |
error | object | The last authentication error that occurred. |
signIn | func | Function to sign in with email and password. |
signUp | func | Function to create a new user account. |
signOut | func | Function to sign the user out. |
updateUser | func | Function to update user metadata. |
resetPassword | func | Function to initiate a password reset. |
Sources: TASK_4_SUMMARY.md
Animation Hooks
While there isn't a dedicated useAnimation file, the project extensively uses a pattern of combining useRef, useEffect, and the Animated API to create custom, reusable animation logic within components. This pattern can be considered an inline custom hook.
Sources: App.js:61-110, src/features/home/screens/HomeScreen.js:28-71
AnimatedTabIcon Pattern
The AnimatedTabIcon in App.js is a prime example. It encapsulates the logic for scaling and rotating an icon when it is focused.
// File: App.js:61-110
const AnimatedTabIcon = ({ name, color, focused, IconComponent }) => {
const scaleAnim = React.useRef(new Animated.Value(1)).current;
const rotateAnim = React.useRef(new Animated.Value(0)).current;
React.useEffect(() => {
if (focused) {
// ...
Animated.parallel([
Animated.spring(scaleAnim, {
toValue: 1.2,
friction: 3,
useNativeDriver: Platform.OS !== "web",
}),
Animated.timing(rotateAnim, {
toValue: 1,
duration: 300,
useNativeDriver: Platform.OS !== "web",
}),
]).start();
} else {
// ... reverse animation
}
}, [focused]);
const spin = rotateAnim.interpolate(/* ... */);
return (
<Animated.View style={{ transform: [{ scale: scaleAnim }, { rotate: spin }] }}>
<IconComponent name={name} size={24} color={color} />
</Animated.View>
);
};
This pattern is repeated for other animated components like FeatureCard and QuickActionButton in HomeScreen.js, demonstrating a consistent approach to component-level animations.
Sources: App.js:61-110, src/features/home/screens/HomeScreen.js:28-71, 131-157
Conclusion
The custom hooks in eefashiondesign are a cornerstone of the application's architecture. They provide a robust, scalable, and maintainable way to manage complex logic, state, and side effects. The general-purpose hooks in src/hooks/index.js offer a powerful toolkit for common tasks, while the state management hooks like useAuth create a clean and decoupled system for interacting with backend services and global state. This commitment to the hook pattern results in a more declarative and developer-friendly codebase.