function useAsyncQueuer<TValue, TSelected>(
fn,
options,
selector): ReactAsyncQueuer<TValue, TSelected>;
Defined in: react-pacer/src/async-queuer/useAsyncQueuer.ts:235
A lower-level React hook that creates an AsyncQueuer instance for managing an async queue of items.
Features:
Tasks are processed concurrently up to the configured concurrency limit. When a task completes, the next pending task is processed if below the concurrency limit.
Error Handling:
The hook uses TanStack Store for reactive state management. You can subscribe to state changes in two ways:
1. Using queuer.Subscribe HOC (Recommended for component tree subscriptions)
Use the Subscribe HOC to subscribe to state changes deep in your component tree without needing to pass a selector to the hook. This is ideal when you want to subscribe to state in child components.
2. Using the selector parameter (For hook-level subscriptions)
The selector parameter allows you to specify which state changes will trigger a re-render at the hook level, optimizing performance by preventing unnecessary re-renders when irrelevant state changes occur.
By default, there will be no reactive state subscriptions and you must opt-in to state tracking by providing a selector function or using the Subscribe HOC. This prevents unnecessary re-renders and gives you full control over when your component updates.
Available state properties:
By default, the hook stops the queuer and aborts any in-flight task executions when the component unmounts. Abort only cancels underlying operations (e.g. fetch) when the abort signal from getAbortSignal() is passed to them. Use the onUnmount option to customize this. For example, to flush pending items instead:
const queuer = useAsyncQueuer(fn, {
concurrency: 2,
started: false,
onUnmount: (q) => q.flush()
});
Note: For async utils, flush() returns a Promise and runs fire-and-forget in the cleanup. If your task function updates React state, those updates may run after the component has unmounted, which can cause "setState on unmounted component" warnings. Guard your callbacks accordingly when using onUnmount with flush.
TValue
TSelected = { }
(value) => Promise<any>
ReactAsyncQueuerOptions<TValue, TSelected> = {}
(state) => TSelected
ReactAsyncQueuer<TValue, TSelected>
// Default behavior - no reactive state subscriptions
const asyncQueuer = useAsyncQueuer(
async (item) => {
const result = await processItem(item);
return result;
},
{ concurrency: 2, maxSize: 100, started: false }
);
// Subscribe to state changes deep in component tree using Subscribe HOC
<asyncQueuer.Subscribe selector={(state) => ({ size: state.size, isRunning: state.isRunning })}>
{({ size, isRunning }) => (
<div>Queue: {size} items, {isRunning ? 'Processing' : 'Idle'}</div>
)}
</asyncQueuer.Subscribe>
// Opt-in to re-render when queue size changes at hook level (optimized for displaying queue length)
const asyncQueuer = useAsyncQueuer(
async (item) => {
const result = await processItem(item);
return result;
},
{ concurrency: 2, maxSize: 100, started: false },
(state) => ({
size: state.size,
isEmpty: state.isEmpty,
isFull: state.isFull
})
);
// Opt-in to re-render when processing state changes (optimized for loading indicators)
const asyncQueuer = useAsyncQueuer(
async (item) => {
const result = await processItem(item);
return result;
},
{ concurrency: 2, maxSize: 100, started: false },
(state) => ({
isRunning: state.isRunning,
isIdle: state.isIdle,
status: state.status,
activeItems: state.activeItems,
pendingTick: state.pendingTick
})
);
// Opt-in to re-render when execution metrics change (optimized for stats display)
const asyncQueuer = useAsyncQueuer(
async (item) => {
const result = await processItem(item);
return result;
},
{ concurrency: 2, maxSize: 100, started: false },
(state) => ({
successCount: state.successCount,
errorCount: state.errorCount,
settledCount: state.settledCount,
expirationCount: state.expirationCount,
rejectionCount: state.rejectionCount
})
);
// Opt-in to re-render when results are available (optimized for data display)
const asyncQueuer = useAsyncQueuer(
async (item) => {
const result = await processItem(item);
return result;
},
{
concurrency: 2,
maxSize: 100,
started: false,
onSuccess: (result) => {
console.log('Item processed:', result);
},
onError: (error) => {
console.error('Processing failed:', error);
}
},
(state) => ({
lastResult: state.lastResult,
successCount: state.successCount
})
);
// Add items to queue
asyncQueuer.addItem(newItem);
// Start processing
asyncQueuer.start();
// Access the selected state (will be empty object {} unless selector provided)
const { size, isRunning, activeItems } = asyncQueuer.state;