Skip to content

Commit

Permalink
Merge pull request #106 from charlie-tango/fix/expose-debounced-value…
Browse files Browse the repository at this point in the history
…-controls

fix: expose the control methods on useDebouncedValue
  • Loading branch information
thebuilder authored Aug 13, 2024
2 parents 8132a18 + 05bce2f commit 2d740ad
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 6 deletions.
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ setDebouncedValue("World");
console.log(debouncedValue); // Will log "Hello" until 500ms has passed
```

The `setDebouncedValue` also contains a few control methods, that can be useful:

- `flush`: Call the callback immediately, and cancel debouncing.
- `cancel`: Cancel debouncing, and the callback will never be called.
- `isPending`: Check if the callback is waiting to be called.
You can use them like this:

```tsx
const [debouncedValue, setDebouncedValue] = useDebouncedValue(
initialValue,
500,
);

setDebouncedValue("Hello");
setDebouncedValue.isPending(); // true
setDebouncedValue.flush(); // Logs "Hello"
setDebouncedValue("world");
setDebouncedValue.cancel(); // Will never log "world"
```

### `useDebouncedCallback`

Debounce a callback function. The callback will only be called after the delay has passed without the function being called again.
Expand All @@ -58,10 +78,10 @@ debouncedCallback("Hello");
debouncedCallback("World"); // Will only log "World" after 500ms
```

The `debouncedCallback` also contains a few methods, that can be useful:
The `debouncedCallback` also contains a few control methods, that can be useful:

- `flush`: Call the callback immediately, and cancel the debounce.
- `cancel`: Cancel the debounce, and the callback will never be called.
- `flush`: Call the callback immediately, and cancel debouncing.
- `cancel`: Cancel debouncing, and the callback will never be called.
- `isPending`: Check if the callback is waiting to be called.

You can use them like this:
Expand Down
27 changes: 26 additions & 1 deletion src/__tests__/useDebouncedValue.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ test("should update if 'initial value' is changed", async () => {
const { result, rerender } = renderHook((initialValue = "hello") =>
useDebouncedValue(initialValue, 500),
);

expect(result.current[0]).toBe("hello");
rerender("world");

Expand Down Expand Up @@ -77,3 +76,29 @@ test("should update the value immediately if leading is true", async () => {
vi.runAllTimers();
});
});

test("should be able to flush the debounce", async () => {
const initialValue = "hello";
const { result } = renderHook(() => useDebouncedValue(initialValue, 500));

expect(result.current[0]).toBe(initialValue);
result.current[1]("world");
expect(result.current[1].isPending()).toBe(true);
act(() => {
result.current[1].flush();
});
expect(result.current[0]).toBe("world");
});

test("should be able to cancel the debounce", async () => {
const initialValue = "hello";
const { result } = renderHook(() => useDebouncedValue(initialValue, 500));

expect(result.current[0]).toBe(initialValue);
result.current[1]("world");
expect(result.current[1].isPending()).toBe(true);
act(() => {
result.current[1].cancel();
});
expect(result.current[0]).toBe("hello");
});
4 changes: 2 additions & 2 deletions src/hooks/useDebouncedValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function useDebouncedValue<T>(
initialValue: T,
wait: number,
options: DebounceOptions = { trailing: true },
): [T, (value: T) => void] {
) {
const [debouncedValue, setDebouncedValue] = useState<T>(initialValue);
const previousValueRef = useRef<T | undefined>(initialValue);

Expand All @@ -47,5 +47,5 @@ export function useDebouncedValue<T>(
previousValueRef.current = initialValue;
}

return [debouncedValue, updateDebouncedValue];
return [debouncedValue, updateDebouncedValue] as const;
}

0 comments on commit 2d740ad

Please sign in to comment.