rehookd
v1.0.0
Published
A React hook framework for optimized state management, real-time collaboration, and more.
Downloads
3
Maintainers
Readme
Rehookd Framework Documentation
Introduction
Rehookd is a powerful React hook framework designed to simplify and optimize state management, concurrency, real-time collaboration, UI handling, and more. The framework introduces a series of macro hooks, each combining multiple hooks to handle specific use cases, such as managing state with undo/redo, handling asynchronous tasks with workers, and virtualizing scroll lists for better performance.
This documentation will guide you through installing the framework, understanding each macro, and using them with detailed examples that demonstrate their full potential.
Installation
To install Rehookd, use npm:
npm install rehookd
Once installed, you can import the necessary macros or hooks directly into your React components:
import { useStateWithHistory, useQueue } from 'rehookd';
Macro Hooks Overview
1. useStateWithHistory (undo/redo and queue)
useStateWithHistory
This hook manages state with undo and redo functionality. It maintains a history of changes, allowing you to revert or redo actions as needed.
useQueue
Adds the ability to manage a queue of state changes or actions, useful for handling sequences like notifications, task sequences, or batched state changes.
Usage Example:
import { useStateWithHistory, useQueue } from 'rehookd';
const TaskQueueComponent = () => {
// Initial state with undo/redo functionality
const { state, setState, undo, redo, canUndo, canRedo } = useStateWithHistory('Initial State');
// Queue to handle multiple tasks
const { enqueue, dequeue, queue } = useQueue();
const handleStateChange = () => {
setState('Updated State');
};
const handleUndo = () => {
if (canUndo) undo();
};
const handleRedo = () => {
if (canRedo) redo();
};
const addTaskToQueue = (task) => {
enqueue(task);
};
const processQueue = () => {
const nextTask = dequeue();
if (nextTask) nextTask(); // Process the task
};
return (
<div>
<p>Current State: {state}</p>
<button onClick={handleStateChange}>Update State</button>
<button onClick={handleUndo} disabled={!canUndo}>Undo</button>
<button onClick={handleRedo} disabled={!canRedo}>Redo</button>
<button onClick={() => addTaskToQueue(() => console.log('Task 1'))}>Add Task 1</button>
<button onClick={processQueue}>Process Queue</button>
<p>Queue Length: {queue.length}</p>
</div>
);
};
2. useStateManagement (global state, selectors, sync, and immutability)
useSelector
Selects specific parts of the state for optimized re-renders. This is useful when you need to update only part of a component based on global or local state changes.
useStateSync
Synchronizes state across multiple components without the need for React Context or external state libraries.
useAtom / useStore
Manages global or shared state in a lightweight, Recoil/Jotai-like manner, allowing for a central store of state that is easy to access from any component.
useImmutableState
Ensures immutability in state management, preventing accidental mutations and ensuring a safe state update process.
useProxyState
Automatically tracks and updates state through a proxy, removing the need for manual updates or setter functions.
Usage Example:
import { useStore, useSelector, useStateSync, useImmutableState, useProxyState } from 'rehookd';
const GlobalStateComponent = () => {
// Create a global store with some initial state
const [globalState, setGlobalState] = useStore('globalKey', { count: 0, name: 'John' });
// Select part of the state for optimized re-renders
const name = useSelector('globalKey', (state) => state.name);
// Synchronize state across components
const [syncedState, setSyncedState] = useStateSync('globalKey');
// Immutable state management
const [immutableState, setImmutableState] = useImmutableState('immutableKey', { value: 100 });
// Proxy state for automatic updates
const proxyState = useProxyState('proxyKey', { clicks: 0 });
const incrementCounter = () => {
setGlobalState((prevState) => ({ ...prevState, count: prevState.count + 1 }));
};
return (
<div>
<p>Global Count: {globalState.count}</p>
<p>Name: {name}</p>
<button onClick={incrementCounter}>Increment Counter</button>
<p>Synced Count: {syncedState.count}</p>
<button onClick={() => setSyncedState({ count: syncedState.count + 1 })}>Sync Increment</button>
<p>Immutable Value: {immutableState.value}</p>
<button onClick={() => setImmutableState({ value: immutableState.value + 10 })}>Increment Immutable Value</button>
<p>Proxy Clicks: {proxyState.clicks}</p>
<button onClick={() => proxyState.clicks++}>Increment Proxy Clicks</button>
</div>
);
};
3. useTimeManagement (timers, countdowns, and scheduling)
useTimeout
Delays actions or state updates by a specified amount of time.
useCountdown
Manages countdown timers for time-based events like promotions or deadlines.
useSchedule
Schedules tasks to run at specific intervals or times.
Usage Example:
import { useTimeout, useCountdown, useSchedule } from 'rehookd';
const TimeManagementComponent = () => {
// Delay an action by 2 seconds
useTimeout(() => console.log('Action delayed by 2 seconds'), 2000);
// Countdown from 10 to 0
const [timeLeft, startCountdown, resetCountdown] = useCountdown(10);
// Schedule a task to run every 1 second
useSchedule(() => console.log('Scheduled task running every second'), 1000);
return (
<div>
<p>Time Left: {timeLeft}</p>
<button onClick={startCountdown}>Start Countdown</button>
<button onClick={resetCountdown}>Reset Countdown</button>
</div>
);
};
4. useConcurrency (workers, tasks, loops, and async operations)
useWorker
Manages background tasks using Web Workers to offload expensive computations.
useConcurrentTasks
Manages multiple asynchronous tasks in parallel, ensuring efficient task processing.
useAsyncLoop
Continuously runs tasks or loops asynchronously until a condition is met.
useFork
Manages parallel execution of functions or tasks, similar to forking processes in other languages.
Usage Example:
import { useWorker, useConcurrentTasks, useAsyncLoop, useFork } from 'rehookd';
const ConcurrencyComponent = () => {
const worker = useWorker((data) => {
// Expensive computation handled in the worker
return data.map(item => item * 2);
});
const tasks = [
() => fetch('https://api.example.com/task1').then(res => res.json()),
() => fetch('https://api.example.com/task2').then(res => res.json()),
];
const { results, runTasks } = useConcurrentTasks(tasks);
useAsyncLoop(() => {
console.log('Polling data every second');
}, 1000, () => results.length > 0);
useFork(() => console.log('Task 1'), () => console.log('Task 2'));
return (
<div>
<button onClick={() => worker.postMessage([1, 2, 3])}>Run Worker</button>
<button onClick={runTasks}>Run Concurrent Tasks</button>
</div>
);
};
5. useRealTime (sockets, presence, and collaboration)
useSocket
Manages WebSocket connections for real-time communication like chats and live updates.
usePresence
Tracks and manages user presence in collaborative applications (e.g., online/offline, typing status).
useCollaborativeState
Synchronizes state across multiple users in real-time, ideal for collaborative environments like document editing.
Usage Example:
import { useSocket, usePresence, useCollaborativeState } from 'rehookd';
const RealTimeComponent = () => {
const { sendMessage, receiveMessage } = useSocket('ws://example.com/socket');
const { isOnline, setPresence } = usePresence();
const [collabState, setCollabState] = useCollaborativeState('doc', { content: '' });
receiveMessage((message) => {
console.log('Received:', message);
});
const handleSend = () => {
sendMessage('Hello, World!');
};
return (
<div>
<p>Online Status: {isOnline ? 'Online' : 'Offline'}</p>
<button onClick={() => setPresence(!isOnline)}>Toggle Presence</button>
<textarea
value={collabState.content}
onChange={(e) => setCollabState({ content: e.target.value })}placeholder="Collaborative Document Editing"
/>
<button onClick={handleSend}>Send Message</button>
</div>
);
};
6. useUserActivity (idle detection, page visibility, and clipboard)
useIdle
Detects when the user becomes idle for a specified period. This is useful for session timeouts, showing idle warnings, or triggering background tasks.
usePageVisibility
Detects if the current page is visible or hidden (e.g., to pause media playback or animation when the user switches tabs).
useClipboard
Provides a way to read and write data to the clipboard, supporting features like copying text from your application.
Usage Example:
import { useIdle, usePageVisibility, useClipboard } from 'rehookd';
const ActivityTrackerComponent = () => {
const isIdle = useIdle(5000); // Detect if idle for 5 seconds
const isVisible = usePageVisibility();
const { copyToClipboard, readFromClipboard } = useClipboard();
const handleCopy = () => {
copyToClipboard('Copied to clipboard!');
};
return (
<div>
<p>User is {isIdle ? 'Idle' : 'Active'}</p>
<p>Page is {isVisible ? 'Visible' : 'Hidden'}</p>
<button onClick={handleCopy}>Copy Text</button>
<button onClick={() => readFromClipboard().then((text) => alert(`Clipboard: ${text}`))}>
Read Clipboard
</button>
</div>
);
};
7. useScrollAndNavigation (scroll restoration, route guards, lazy loading)
useScrollRestoration
Automatically restores the scroll position when navigating between routes, ensuring that users return to the same scroll position they left.
useRouteGuard
Prevents unauthorized access to routes by enforcing specific conditions before navigation.
useLazyRouteLoader
Lazily loads routes to optimize performance, especially in large applications where loading everything upfront would be inefficient.
Usage Example:
import { useScrollRestoration, useRouteGuard, useLazyRouteLoader } from 'rehookd';
const NavigationComponent = () => {
useScrollRestoration(); // Automatically restore scroll position on navigation
const isAuthenticated = false; // Replace with actual auth logic
useRouteGuard(isAuthenticated, '/login'); // Prevent navigation to protected routes
const { loadRoute, isLoading } = useLazyRouteLoader(() => import('./HeavyComponent'));
return (
<div>
<button onClick={loadRoute}>Load Heavy Component</button>
{isLoading ? <p>Loading...</p> : <HeavyComponent />}
</div>
);
};
8. useSpeech (recognition, synthesis, and media handling)
useSpeechRecognition
Integrates speech recognition, allowing voice commands or dictation in your application.
useSpeechSynthesis
Handles text-to-speech functionality for user feedback or accessibility.
useMeta
Dynamically updates meta tags for better SEO and social sharing, ensuring your app’s metadata is always relevant.
Usage Example:
import { useSpeechRecognition, useSpeechSynthesis, useMeta } from 'rehookd';
const SpeechComponent = () => {
const { transcript, startRecognition, stopRecognition } = useSpeechRecognition();
const { speak, cancelSpeech } = useSpeechSynthesis();
// Dynamically update meta tags
useMeta({ title: 'Speech Example', description: 'A speech recognition and synthesis demo' });
return (
<div>
<p>Transcript: {transcript}</p>
<button onClick={startRecognition}>Start Recognition</button>
<button onClick={stopRecognition}>Stop Recognition</button>
<button onClick={() => speak('Hello, world!')}>Speak</button>
<button onClick={cancelSpeech}>Cancel Speech</button>
</div>
);
};
9. useVirtual (scroll and lists)
useVirtualScroll
Optimizes scrolling performance by only rendering the visible portion of a large dataset (virtual scrolling).
useVirtualList
Efficiently manages large lists or tables by rendering only the visible rows or items, improving the performance of large datasets.
Usage Example:
import { useVirtualScroll, useVirtualList } from 'rehookd';
const VirtualListComponent = () => {
const items = Array.from({ length: 10000 }, (_, i) => `Item ${i + 1}`);
const { visibleItems, containerProps } = useVirtualList(items, 50); // Assume 50px height per item
return (
<div {...containerProps} style={{ height: '400px', overflow: 'auto' }}>
{visibleItems.map((item, index) => (
<div key={index} style={{ height: '50px' }}>
{item}
</div>
))}
</div>
);
};
10. useReactiveStreams (observables, subjects, and pipes)
useObservable
Handles reactive streams of data, allowing components to subscribe to and react to asynchronous events.
useSubject
Manages a reactive subject, allowing components to both emit and subscribe to a stream of values.
usePipe
Chains operations together in a pipeline to handle complex data transformations, similar to RxJS pipes.
Usage Example:
import { useObservable, useSubject, usePipe } from 'rehookd';
const ReactiveStreamsComponent = () => {
const { subscribe, emit } = useSubject();
subscribe((data) => {
console.log('Received data:', data);
});
const pipeline = usePipe(
(data) => data * 2,
(data) => data + 1
);
const handleEmit = () => {
const transformedData = pipeline.execute(5); // Pipeline: (5 * 2) + 1 = 11
emit(transformedData);
};
return (
<div>
<button onClick={handleEmit}>Emit Data</button>
</div>
);
};
11. useUI (modals, snackbars, tabs, and gestures)
useModal
Manages modal dialogs, including open/close state and animations.
useSnackbar
Displays snackbars or toast notifications for user feedback.
useTabs
Manages tabbed interfaces, allowing easy navigation between sections of a page.
useGestures
Tracks touch and gesture-based interactions, such as swiping or pinching, especially useful for mobile-friendly UIs.
Usage Example:
import { useModal, useSnackbar, useTabs, useGestures } from 'rehookd';
const UIComponent = () => {
const { open, close, isOpen } = useModal();
const { showSnackbar } = useSnackbar();
const { activeTab, setActiveTab } = useTabs(['Tab1', 'Tab2', 'Tab3']);
const { detectSwipe } = useGestures();
detectSwipe((direction) => console.log('Swipe detected:', direction));
return (
<div>
<button onClick={open}>Open Modal</button>
<button onClick={() => showSnackbar('Hello, Snackbar!')}>Show Snackbar</button>
{isOpen && <div>Modal Content <button onClick={close}>Close</button></div>}
<div>
<button onClick={() => setActiveTab('Tab1')}>Tab 1</button>
<button onClick={() => setActiveTab('Tab2')}>Tab 2</button>
<button onClick={() => setActiveTab('Tab3')}>Tab 3</button>
</div>
<p>Active Tab: {activeTab}</p>
</div>
);
};
12. useWebComponents (custom elements, shadow DOM, slots)
useCustomElement
Integrates custom HTML elements or Web Components into your React application.
useShadowDOM
Encapsulates styles and content in a Shadow DOM, preventing style leakage.
useSlot
Allows flexible content distribution in components, similar to Web Component slots.
Usage Example:
import { useCustomElement, useShadowDOM, useSlot } from 'rehookd';
class MyCustomElement extends HTMLElement {
connectedCallback() {
this.innerHTML = `<div><slot></slot></div>`;
}
}
const WebComponentExample = () => {
useCustomElement('my-custom-element', MyCustomElement);
const containerRef = useShadowDOM();
const { setSlotContent } = useSlot(containerRef);
return (
<div ref={containerRef}>
<my-custom-element>
<span>Content inside the Web Component</span>
</my-custom-element>
<button onClick={() => setSlotContent('Updated content in slot')}>
Update Slot Content
</button>
</div>
);
};
13. useDatabaseAndTransactions (ORM and transactions)
useORM
Simplifies database interactions by providing an ORM-like hook to manage data models.
useTransaction
Handles batched updates
or state changes as atomic transactions, ensuring consistency and preventing partial updates.
Usage Example:
import { useORM, useTransaction } from 'rehookd';
const DatabaseComponent = () => {
const { find, insert, update } = useORM('users');
const { startTransaction, commit, rollback } = useTransaction();
const addUser = () => {
startTransaction();
insert({ id: 1, name: 'Alice' });
commit();
};
const handleUpdate = () => {
startTransaction();
update(1, { name: 'Updated Alice' });
commit();
};
return (
<div>
<button onClick={addUser}>Add User</button>
<button onClick={handleUpdate}>Update User</button>
</div>
);
};
14. useBrowserNotifications
useNotification
Manages browser notifications to engage users, useful for event alerts or reminders.
Usage Example:
import { useNotification } from 'rehookd';
const NotificationComponent = () => {
const { requestPermission, showNotification } = useNotification();
const sendNotification = () => {
requestPermission().then(() => {
showNotification('New Message', { body: 'You have a new message!' });
});
};
return <button onClick={sendNotification}>Send Notification</button>;
};
15. useTaskLoop (repeated task execution)
useLoop
Continuously runs a task until a condition is satisfied, automating processes like data fetching or event polling.
Usage Example:
import { useLoop } from 'rehookd';
const TaskLoopComponent = () => {
const [count, setCount] = useState(0);
useLoop(() => {
setCount((prev) => prev + 1);
}, 1000, () => count >= 10);
return <p>Count: {count}</p>;
};
16. useLazyEvaluation (deferred computation)
useLazyEvaluation
Defers calculations until they are absolutely necessary, optimizing performance for expensive operations.
Usage Example:
import { useLazyEvaluation } from 'rehookd';
const ExpensiveComponent = () => {
const { evaluate, getResult } = useLazyEvaluation(() => {
return Array(1000000).fill(0).reduce((acc, _, i) => acc + i, 0);
});
return (
<div>
<p>Result: {getResult()}</p>
<button onClick={evaluate}>Evaluate Expensive Calculation</button>
</div>
);
};
17. useActivity (tracking component usage)
useActivity
Assigns unique IDs to components and tracks their usage (e.g., clicks, focus events) in real-time, saving data to localStorage. Data can later be sent to a backend for analytics.
Usage Example:
import { useActivity } from 'rehookd';
const ActivityComponent = () => {
const { componentId, trackClick, trackFocus, getActivityData, clearActivityData } = useActivity('ComponentA');
const sendDataToBackend = () => {
const data = getActivityData();
console.log('Sending activity data:', data);
clearActivityData();
};
return (
<div>
<p>Component ID: {componentId}</p>
<button onClick={trackClick}>Track Click</button>
<input onFocus={trackFocus} placeholder="Focus here" />
<button onClick={sendDataToBackend}>Send Activity Data</button>
</div>
);
};
Conclusion
Rehookd provides a suite of powerful, reusable hooks for React developers. From state management with undo/redo, concurrency, and real-time communication, to UI components and virtualized scrolling, this framework simplifies complex workflows and boosts performance.