Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/fair-donuts-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@tanstack/react-pacer': patch
'@tanstack/preact-pacer': patch
---

Use the latest `onUnmount` callback during cleanup so adapter teardown reflects current options instead of the initial render.
8 changes: 5 additions & 3 deletions packages/preact-pacer/src/debouncer/useDebouncer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'preact/hooks'
import { useEffect, useMemo, useRef, useState } from 'preact/hooks'
import { Debouncer } from '@tanstack/pacer/debouncer'
import { shallow, useStore } from '@tanstack/preact-store'
import { useDefaultPacerOptions } from '../provider/PacerProvider'
Expand Down Expand Up @@ -193,12 +193,14 @@ export function useDebouncer<TFn extends AnyFunction, TSelected = {}>(

debouncer.fn = fn
debouncer.setOptions(mergedOptions)
const onUnmountRef = useRef(mergedOptions.onUnmount)
onUnmountRef.current = mergedOptions.onUnmount

/* eslint-disable react-hooks/exhaustive-deps -- cleanup only; runs on unmount */
useEffect(() => {
return () => {
if (mergedOptions.onUnmount) {
mergedOptions.onUnmount(debouncer)
if (onUnmountRef.current) {
onUnmountRef.current(debouncer)
} else {
debouncer.cancel()
}
Expand Down
8 changes: 5 additions & 3 deletions packages/react-pacer/src/async-debouncer/useAsyncDebouncer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
import { AsyncDebouncer } from '@tanstack/pacer/async-debouncer'
import { shallow, useStore } from '@tanstack/react-store'
import { useDefaultPacerOptions } from '../provider/PacerProvider'
Expand Down Expand Up @@ -248,14 +248,16 @@ export function useAsyncDebouncer<TFn extends AnyAsyncFunction, TSelected = {}>(

asyncDebouncer.fn = fn
asyncDebouncer.setOptions(mergedOptions)
const onUnmountRef = useRef(mergedOptions.onUnmount)
onUnmountRef.current = mergedOptions.onUnmount

const state = useStore(asyncDebouncer.store, selector, shallow)

/* eslint-disable react-hooks/exhaustive-deps, @eslint-react/exhaustive-deps, react-compiler/react-compiler -- unmount cleanup only; empty deps keep teardown stable */
useEffect(() => {
return () => {
if (mergedOptions.onUnmount) {
mergedOptions.onUnmount(asyncDebouncer)
if (onUnmountRef.current) {
onUnmountRef.current(asyncDebouncer)
} else {
asyncDebouncer.cancel()
asyncDebouncer.abort()
Expand Down
8 changes: 5 additions & 3 deletions packages/react-pacer/src/debouncer/useDebouncer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
import { Debouncer } from '@tanstack/pacer/debouncer'
import { shallow, useStore } from '@tanstack/react-store'
import { useDefaultPacerOptions } from '../provider/PacerProvider'
Expand Down Expand Up @@ -196,12 +196,14 @@ export function useDebouncer<TFn extends AnyFunction, TSelected = {}>(

debouncer.fn = fn
debouncer.setOptions(mergedOptions)
const onUnmountRef = useRef(mergedOptions.onUnmount)
onUnmountRef.current = mergedOptions.onUnmount

/* eslint-disable react-hooks/exhaustive-deps, @eslint-react/exhaustive-deps, react-compiler/react-compiler -- unmount cleanup only; empty deps keep teardown stable */
useEffect(() => {
return () => {
if (mergedOptions.onUnmount) {
mergedOptions.onUnmount(debouncer)
if (onUnmountRef.current) {
onUnmountRef.current(debouncer)
} else {
debouncer.cancel()
}
Expand Down
8 changes: 5 additions & 3 deletions packages/react-pacer/src/rate-limiter/useRateLimiter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
import { RateLimiter } from '@tanstack/pacer/rate-limiter'
import { shallow, useStore } from '@tanstack/react-store'
import { useDefaultPacerOptions } from '../provider/PacerProvider'
Expand Down Expand Up @@ -223,12 +223,14 @@ export function useRateLimiter<TFn extends AnyFunction, TSelected = {}>(

rateLimiter.fn = fn
rateLimiter.setOptions(mergedOptions)
const onUnmountRef = useRef(mergedOptions.onUnmount)
onUnmountRef.current = mergedOptions.onUnmount

/* eslint-disable react-hooks/exhaustive-deps, @eslint-react/exhaustive-deps, react-compiler/react-compiler -- unmount cleanup only; empty deps keep teardown stable */
useEffect(() => {
return () => {
if (mergedOptions.onUnmount) {
mergedOptions.onUnmount(rateLimiter)
if (onUnmountRef.current) {
onUnmountRef.current(rateLimiter)
}
}
}, [])
Expand Down