@akbeniwal/react-native-hooks
v1.0.4
Published
A high-performance collection of React Native hooks optimized for performance, memory safety and developer experience.
Maintainers
Readme
@akbeniwal/react-native-hooks ⚡
A high-performance, lightweight, and type-safe collection of 16 custom React Native hooks optimized for performance, memory-leak prevention, and smooth 60fps UX.
Key Features 🌟
- 100% Dependency-Free & Lightweight: No external peer dependencies like
@react-native-clipboard/clipboardor@react-native-community/netinforequired. - Speed & Latency Testing: Monitor internet connection status, round-trip ping latency, quality classification, and measure download speed in Mbps on-demand.
- Android-Specific Back Button Hooks: Custom hooks for back-press events and standard "Double-Tap to Exit" Toast notifications.
- Optimized Performance: Internal callbacks are isolated inside
useRefto prevent system listeners (keyboard, dimensions, back-handlers, app-states) from registering and tearing down repeatedly. - TypeScript Ready: Fully typed out-of-the-box with auto-generated declaration maps.
- Cross-Platform: Support for Android, iOS, and React Native Web.
Installation 📦
npm install @akbeniwal/react-native-hooks
# or
yarn add @akbeniwal/react-native-hooksTable of Hooks 📚
| Hook | Purpose | Platform |
| :--- | :--- | :--- |
| useAppState | Tracks active/inactive/background app focus states with callbacks. | iOS, Android, Web |
| useBackHandler | Android physical/virtual hardware back button press. | Android |
| useClipboard | Reads & writes to the system clipboard with copied feedback callback. | iOS, Android, Web |
| useCountdown | Full-featured countdown timer with pause, reset, and tick callbacks. | iOS, Android, Web |
| useDebounce | Debounces state values with optional change triggers. | iOS, Android, Web |
| useKeyboard | Tracks virtual keyboard display status and dynamic height. | iOS, Android |
| useNetworkStatus | Monitors internet connection, latency, speed test in Mbps, and offline alerts. | iOS, Android, Web |
| usePrevious | Accesses the value of a state/prop from the previous render. | iOS, Android, Web |
| useThrottle | Throttles state update changes. | iOS, Android, Web |
| useToggle | Simple state toggle with onChange, onTrue, and onFalse callbacks. | iOS, Android, Web |
| useAfterInteractions | Defers execution of tasks until layout transition animations finish. | iOS, Android |
| useLayout | Measures dynamic sizing and screen positions of views. | iOS, Android, Web |
| useDoubleTapToExit | Prompts and exits app only on double-pressing Android back button. | Android |
| useDeviceOrientation | Tracks rotation and current orientation status (PORTRAIT / LANDSCAPE). | iOS, Android, Web |
| useInterval | Declarative version of setInterval (prevents stale state closures). | iOS, Android, Web |
| useTimeout | Declarative version of setTimeout (cleans up automatically on unmount). | iOS, Android, Web |
Quick Usage Reference 💡
useAppState
import { useAppState } from '@akbeniwal/react-native-hooks';
const appState = useAppState({
onForeground: () => console.log('App entered foreground!'),
onBackground: () => console.log('App entered background!'),
});useBackHandler
import { useBackHandler } from '@akbeniwal/react-native-hooks';
useBackHandler(() => {
// Return true to prevent default back action
if (hasUnsavedChanges) {
showExitAlert();
return true;
}
return false;
});useClipboard
import { useClipboard } from '@akbeniwal/react-native-hooks';
const [clipboardData, setString] = useClipboard({
onCopy: (text) => console.log(`Copied "${text}" to clipboard!`),
});useCountdown
import { useCountdown } from '@akbeniwal/react-native-hooks';
const { seconds, isActive, start, pause, reset } = useCountdown({
initialSeconds: 60,
onExpire: () => alert('OTP expired!'),
onTick: (secs) => console.log(`${secs} seconds remaining`),
});useDebounce
import { useDebounce } from '@akbeniwal/react-native-hooks';
const [searchQuery, setSearchQuery] = useState('');
const debouncedQuery = useDebounce(searchQuery, 500, (value) => {
fetchSearchResults(value);
});useKeyboard
import { useKeyboard } from '@akbeniwal/react-native-hooks';
const { keyboardShown, keyboardHeight } = useKeyboard({
onShow: (height) => console.log(`Keyboard visible with height: ${height}`),
onHide: () => console.log('Keyboard hidden'),
});useNetworkStatus
import { useNetworkStatus } from '@akbeniwal/react-native-hooks';
const {
isConnected,
isInternetReachable,
latencyMs,
connectionQuality,
internetSpeed,
isTestingSpeed,
runSpeedTest
} = useNetworkStatus({
pingIntervalMs: 30000, // Ping Google every 30 seconds
onOnline: () => console.log('Back online! syncing database...'),
onOffline: () => console.log('Network connection lost!'),
});usePrevious
import { usePrevious } from '@akbeniwal/react-native-hooks';
const [count, setCount] = useState(0);
const prevCount = usePrevious(count); // returns count from previous renderuseThrottle
import { useThrottle } from '@akbeniwal/react-native-hooks';
const throttledScrollY = useThrottle(scrollY, 100);useToggle
import { useToggle } from '@akbeniwal/react-native-hooks';
const [isModalOpen, toggleModal] = useToggle(false, {
onTrue: () => console.log('Modal Opened'),
onFalse: () => console.log('Modal Closed'),
});useAfterInteractions
import { useAfterInteractions } from '@akbeniwal/react-native-hooks';
const interactionsFinished = useAfterInteractions(() => {
loadExpensiveChartData();
});useLayout
import { useLayout } from '@akbeniwal/react-native-hooks';
import { View } from 'react-native';
const [layout, onLayout] = useLayout({
onChange: (metrics) => console.log('New layout:', metrics),
});
return <View onLayout={onLayout} />;useDoubleTapToExit
import { useDoubleTapToExit } from '@akbeniwal/react-native-hooks';
// Setup on Android
useDoubleTapToExit('Press back button again to exit the app.');useDeviceOrientation
import { useDeviceOrientation } from '@akbeniwal/react-native-hooks';
const orientation = useDeviceOrientation((currentOrientation) => {
console.log('Orientation changed to:', currentOrientation);
});useInterval
import { useInterval } from '@akbeniwal/react-native-hooks';
useInterval(() => {
// Increments or processes state safely without stale closures
tickCounter();
}, isPaused ? null : 1000);useTimeout
import { useTimeout } from '@akbeniwal/react-native-hooks';
useTimeout(() => {
dismissBanner();
}, 5000);Author 👤
Abhishek Beniwal
- GitHub: @AKBeniwal1700
License 📄
This project is licensed under the MIT License.
