If you are using TanStack Pacer in a React application, we recommend using the React Adapter. The React Adapter provides a set of easy-to-use hooks on top of the core Pacer utilities. If you find yourself wanting to use the core Pacer classes/functions directly, the React Adapter will also re-export everything from the core package.
npm install @tanstack/react-pacer
npm install @tanstack/react-pacer
See the React Functions Reference to see the full list of hooks available in the React Adapter.
Import a react specific hook from the React Adapter.
import { useDebouncedValue } from '@tanstack/react-pacer'
const [instantValue, instantValueRef] = useState(0)
const [debouncedValue, debouncer] = useDebouncedValue(instantValue, {
wait: 1000,
})
import { useDebouncedValue } from '@tanstack/react-pacer'
const [instantValue, instantValueRef] = useState(0)
const [debouncedValue, debouncer] = useDebouncedValue(instantValue, {
wait: 1000,
})
Or import a core Pacer class/function that is re-exported from the React Adapter.
import { debounce, Debouncer } from '@tanstack/react-pacer' // no need to install the core package separately
import { debounce, Debouncer } from '@tanstack/react-pacer' // no need to install the core package separately
If you want a type-safe way to define common options for pacer utilities, TanStack Pacer provides option helpers for each utility. These helpers can be used with React hooks.
import { useDebouncer } from '@tanstack/react-pacer'
import { debouncerOptions } from '@tanstack/pacer'
const commonDebouncerOptions = debouncerOptions({
wait: 1000,
leading: false,
trailing: true,
})
const debouncer = useDebouncer(
(query: string) => fetchSearchResults(query),
{ ...commonDebouncerOptions, key: 'searchDebouncer' }
)
import { useDebouncer } from '@tanstack/react-pacer'
import { debouncerOptions } from '@tanstack/pacer'
const commonDebouncerOptions = debouncerOptions({
wait: 1000,
leading: false,
trailing: true,
})
const debouncer = useDebouncer(
(query: string) => fetchSearchResults(query),
{ ...commonDebouncerOptions, key: 'searchDebouncer' }
)
import { useQueuer } from '@tanstack/react-pacer'
import { queuerOptions } from '@tanstack/pacer'
const commonQueuerOptions = queuerOptions({
concurrency: 3,
addItemsTo: 'back',
})
const queuer = useQueuer(
(item: string) => processItem(item),
{ ...commonQueuerOptions, key: 'itemQueuer' }
)
import { useQueuer } from '@tanstack/react-pacer'
import { queuerOptions } from '@tanstack/pacer'
const commonQueuerOptions = queuerOptions({
concurrency: 3,
addItemsTo: 'back',
})
const queuer = useQueuer(
(item: string) => processItem(item),
{ ...commonQueuerOptions, key: 'itemQueuer' }
)
import { useRateLimiter } from '@tanstack/react-pacer'
import { rateLimiterOptions } from '@tanstack/pacer'
const commonRateLimiterOptions = rateLimiterOptions({
limit: 5,
window: 60000,
windowType: 'sliding',
})
const rateLimiter = useRateLimiter(
(data: string) => sendApiRequest(data),
{ ...commonRateLimiterOptions, key: 'apiRateLimiter' }
)
import { useRateLimiter } from '@tanstack/react-pacer'
import { rateLimiterOptions } from '@tanstack/pacer'
const commonRateLimiterOptions = rateLimiterOptions({
limit: 5,
window: 60000,
windowType: 'sliding',
})
const rateLimiter = useRateLimiter(
(data: string) => sendApiRequest(data),
{ ...commonRateLimiterOptions, key: 'apiRateLimiter' }
)
The React Adapter provides a PacerProvider component that you can use to provide default options to all instances of pacer utilities within your component tree.
import { PacerProvider } from '@tanstack/react-pacer'
// Set default options for react-pacer instances
<PacerProvider
defaultOptions={{
debouncer: { wait: 1000 },
queuer: { concurrency: 3 },
rateLimiter: { limit: 5, window: 60000 },
}}
>
<App />
</PacerProvider>
import { PacerProvider } from '@tanstack/react-pacer'
// Set default options for react-pacer instances
<PacerProvider
defaultOptions={{
debouncer: { wait: 1000 },
queuer: { concurrency: 3 },
rateLimiter: { limit: 5, window: 60000 },
}}
>
<App />
</PacerProvider>
All hooks within the provider will automatically use these default options, which can be overridden on a per-hook basis.
import { useDebouncer } from '@tanstack/react-pacer'
function SearchComponent() {
const debouncer = useDebouncer(
(query: string) => {
console.log('Searching for:', query)
// Perform search
},
{ wait: 500 }
)
return (
<input
onChange={(e) => debouncer.maybeExecute(e.target.value)}
placeholder="Search..."
/>
)
}
import { useDebouncer } from '@tanstack/react-pacer'
function SearchComponent() {
const debouncer = useDebouncer(
(query: string) => {
console.log('Searching for:', query)
// Perform search
},
{ wait: 500 }
)
return (
<input
onChange={(e) => debouncer.maybeExecute(e.target.value)}
placeholder="Search..."
/>
)
}
import { useQueuer } from '@tanstack/react-pacer'
function UploadComponent() {
const queuer = useQueuer(
async (file: File) => {
await uploadFile(file)
},
{ concurrency: 3 }
)
const handleFileSelect = (files: FileList) => {
Array.from(files).forEach((file) => {
queuer.add(file)
})
}
return (
<input
type="file"
multiple
onChange={(e) => {
if (e.target.files) {
handleFileSelect(e.target.files)
}
}}
/>
)
}
import { useQueuer } from '@tanstack/react-pacer'
function UploadComponent() {
const queuer = useQueuer(
async (file: File) => {
await uploadFile(file)
},
{ concurrency: 3 }
)
const handleFileSelect = (files: FileList) => {
Array.from(files).forEach((file) => {
queuer.add(file)
})
}
return (
<input
type="file"
multiple
onChange={(e) => {
if (e.target.files) {
handleFileSelect(e.target.files)
}
}}
/>
)
}
import { useRateLimiter } from '@tanstack/react-pacer'
function ApiComponent() {
const rateLimiter = useRateLimiter(
(data: string) => {
return fetch('/api/endpoint', {
method: 'POST',
body: JSON.stringify({ data }),
})
},
{
limit: 5,
window: 60000,
windowType: 'sliding',
onReject: () => {
alert('Rate limit reached. Please try again later.')
},
}
)
const handleSubmit = () => {
const remaining = rateLimiter.getRemainingInWindow()
if (remaining > 0) {
rateLimiter.maybeExecute('some data')
}
}
return <button onClick={handleSubmit}>Submit</button>
}
import { useRateLimiter } from '@tanstack/react-pacer'
function ApiComponent() {
const rateLimiter = useRateLimiter(
(data: string) => {
return fetch('/api/endpoint', {
method: 'POST',
body: JSON.stringify({ data }),
})
},
{
limit: 5,
window: 60000,
windowType: 'sliding',
onReject: () => {
alert('Rate limit reached. Please try again later.')
},
}
)
const handleSubmit = () => {
const remaining = rateLimiter.getRemainingInWindow()
if (remaining > 0) {
rateLimiter.maybeExecute('some data')
}
}
return <button onClick={handleSubmit}>Submit</button>
}
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.