Skip to content

feat(core): add useDebouncedValue and useThrottledValue - #471

Merged
hyesungoh merged 10 commits into
mainfrom
feat/debounced-throttled-value
Sep 7, 2026
Merged

feat(core): add useDebouncedValue and useThrottledValue#471
hyesungoh merged 10 commits into
mainfrom
feat/debounced-throttled-value

Conversation

@hyesungoh

Copy link
Copy Markdown
Member

Overview

Adds useDebouncedValue and useThrottledValue, the value-shaped counterparts to the existing useDebouncedCallback and useThrottledCallback. The caller keeps owning the state; the hook returns a delayed copy of it.

const [query, setQuery] = useState('');
const debouncedQuery = useDebouncedValue(query, 300);

const [scrollY, setScrollY] = useState(0);
const throttledScrollY = useThrottledValue(scrollY, 100);

Stacked on #470 — this branch targets fix/throttle-trailing-window, not main. useThrottledValue with leading: false depends on the throttle fix in that PR.

Interface

Both take (value, wait, options?) with leading / trailing booleans, matching useDebounce's option shape rather than the edges array that useThrottle still uses. The existing hooks will be aligned to booleans in a later breaking change.

hook leading default trailing default
useDebouncedValue false true
useThrottledValue true true

Design notes

  • The caller owns the state. These hooks derive from a value rather than holding one, which is the same split as useDebouncedCallback / useThrottledCallback. A *State variant that owns the state is a separate question.
  • Nothing is scheduled on mount, so the first change after mount is applied immediately when leading is true. The effect skips when the incoming value is both unchanged and already settled, which also covers StrictMode's double-invoked effects.
  • Values are compared by reference. Passing a new object or array every render keeps the returned value updating; the docs point at usePreservedReference.
  • The two hooks' effect bodies are identical. That duplication follows the existing precedent between useDebouncedCallback and useThrottledCallback; _internal/ currently holds only test utilities.

Checklist

  • Did you write the test code?
  • Have you run yarn run fix to format and lint the code and docs?
  • Have you run yarn run test:coverage to make sure there is no uncovered line?
  • Did you write the JSDoc?

@changeset-bot

changeset-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bebc20b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
react-simplikit Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Size Change: +4.53 kB (+4.35%)

Total Size: 109 kB

📦 View Changed
Filename Size Change
packages/react-simplikit/dist/hooks/useDebouncedValue/useDebouncedValue.cjs 1.11 kB +1.11 kB (new file) 🆕
packages/react-simplikit/dist/hooks/useDebouncedValue/useDebouncedValue.mjs 1.08 kB +1.08 kB (new file) 🆕
packages/react-simplikit/dist/hooks/useThrottledValue/useThrottledValue.cjs 1.15 kB +1.15 kB (new file) 🆕
packages/react-simplikit/dist/hooks/useThrottledValue/useThrottledValue.mjs 1.12 kB +1.12 kB (new file) 🆕
packages/react-simplikit/dist/index.cjs 1.39 kB +40 B (+2.97%)
packages/react-simplikit/dist/index.mjs 1.01 kB +27 B (+2.76%)
ℹ️ View Unchanged
Filename Size
packages/codemod/dist/cli.mjs 6.47 kB
packages/react-simplikit/dist/components/ImpressionArea/ImpressionArea.cjs 1.01 kB
packages/react-simplikit/dist/components/ImpressionArea/ImpressionArea.mjs 984 B
packages/react-simplikit/dist/components/Separated/Separated.cjs 686 B
packages/react-simplikit/dist/components/Separated/Separated.mjs 684 B
packages/react-simplikit/dist/components/SwitchCase/SwitchCase.cjs 701 B
packages/react-simplikit/dist/components/SwitchCase/SwitchCase.mjs 699 B
packages/react-simplikit/dist/hooks/useAsyncEffect/useAsyncEffect.cjs 625 B
packages/react-simplikit/dist/hooks/useAsyncEffect/useAsyncEffect.mjs 614 B
packages/react-simplikit/dist/hooks/useAvoidKeyboard/useAvoidKeyboard.cjs 985 B
packages/react-simplikit/dist/hooks/useAvoidKeyboard/useAvoidKeyboard.mjs 963 B
packages/react-simplikit/dist/hooks/useBodyScrollLock/useBodyScrollLock.cjs 546 B
packages/react-simplikit/dist/hooks/useBodyScrollLock/useBodyScrollLock.mjs 523 B
packages/react-simplikit/dist/hooks/useBooleanState/useBooleanState.cjs 546 B
packages/react-simplikit/dist/hooks/useBooleanState/useBooleanState.mjs 536 B
packages/react-simplikit/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.cjs 790 B
packages/react-simplikit/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.mjs 762 B
packages/react-simplikit/dist/hooks/useConditionalEffect/useConditionalEffect.cjs 955 B
packages/react-simplikit/dist/hooks/useConditionalEffect/useConditionalEffect.mjs 934 B
packages/react-simplikit/dist/hooks/useControlledState/useControlledState.cjs 865 B
packages/react-simplikit/dist/hooks/useControlledState/useControlledState.mjs 855 B
packages/react-simplikit/dist/hooks/useCounter/useCounter.cjs 1.03 kB
packages/react-simplikit/dist/hooks/useCounter/useCounter.mjs 1.01 kB
packages/react-simplikit/dist/hooks/useDebounce/debounce.cjs 463 B
packages/react-simplikit/dist/hooks/useDebounce/debounce.mjs 462 B
packages/react-simplikit/dist/hooks/useDebounce/useDebounce.cjs 973 B
packages/react-simplikit/dist/hooks/useDebounce/useDebounce.mjs 954 B
packages/react-simplikit/dist/hooks/useDebouncedCallback/useDebouncedCallback.cjs 1.15 kB
packages/react-simplikit/dist/hooks/useDebouncedCallback/useDebouncedCallback.mjs 1.12 kB
packages/react-simplikit/dist/hooks/useDoubleClick/useDoubleClick.cjs 965 B
packages/react-simplikit/dist/hooks/useDoubleClick/useDoubleClick.mjs 950 B
packages/react-simplikit/dist/hooks/useGeolocation/useGeolocation.cjs 2.02 kB
packages/react-simplikit/dist/hooks/useGeolocation/useGeolocation.mjs 2.02 kB
packages/react-simplikit/dist/hooks/useImpressionRef/useImpressionRef.cjs 1.22 kB
packages/react-simplikit/dist/hooks/useImpressionRef/useImpressionRef.mjs 1.19 kB
packages/react-simplikit/dist/hooks/useInputState/useInputState.cjs 672 B
packages/react-simplikit/dist/hooks/useInputState/useInputState.mjs 662 B
packages/react-simplikit/dist/hooks/useIntersectionObserver/useIntersectionObserver.cjs 1.07 kB
packages/react-simplikit/dist/hooks/useIntersectionObserver/useIntersectionObserver.mjs 1.04 kB
packages/react-simplikit/dist/hooks/useInterval/useInterval.cjs 837 B
packages/react-simplikit/dist/hooks/useInterval/useInterval.mjs 811 B
packages/react-simplikit/dist/hooks/useIsClient/useIsClient.cjs 585 B
packages/react-simplikit/dist/hooks/useIsClient/useIsClient.mjs 574 B
packages/react-simplikit/dist/hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.cjs 577 B
packages/react-simplikit/dist/hooks/useIsomorphicLayoutEffect/useIsomorphicLayoutEffect.mjs 575 B
packages/react-simplikit/dist/hooks/useKeyboardHeight/useKeyboardHeight.cjs 685 B
packages/react-simplikit/dist/hooks/useKeyboardHeight/useKeyboardHeight.mjs 666 B
packages/react-simplikit/dist/hooks/useList/useList.cjs 952 B
packages/react-simplikit/dist/hooks/useList/useList.mjs 930 B
packages/react-simplikit/dist/hooks/useLoading/useLoading.cjs 919 B
packages/react-simplikit/dist/hooks/useLoading/useLoading.mjs 909 B
packages/react-simplikit/dist/hooks/useLongPress/useLongPress.cjs 1.68 kB
packages/react-simplikit/dist/hooks/useLongPress/useLongPress.mjs 1.64 kB
packages/react-simplikit/dist/hooks/useMap/useMap.cjs 730 B
packages/react-simplikit/dist/hooks/useMap/useMap.mjs 713 B
packages/react-simplikit/dist/hooks/useNetworkStatus/useNetworkStatus.cjs 1.2 kB
packages/react-simplikit/dist/hooks/useNetworkStatus/useNetworkStatus.mjs 1.18 kB
packages/react-simplikit/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.cjs 789 B
packages/react-simplikit/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.mjs 758 B
packages/react-simplikit/dist/hooks/usePageVisibility/usePageVisibility.cjs 931 B
packages/react-simplikit/dist/hooks/usePageVisibility/usePageVisibility.mjs 912 B
packages/react-simplikit/dist/hooks/usePreservedCallback/usePreservedCallback.cjs 691 B
packages/react-simplikit/dist/hooks/usePreservedCallback/usePreservedCallback.mjs 675 B
packages/react-simplikit/dist/hooks/usePreservedReference/usePreservedReference.cjs 805 B
packages/react-simplikit/dist/hooks/usePreservedReference/usePreservedReference.mjs 789 B
packages/react-simplikit/dist/hooks/usePrevious/usePrevious.cjs 643 B
packages/react-simplikit/dist/hooks/usePrevious/usePrevious.mjs 635 B
packages/react-simplikit/dist/hooks/useRefEffect/useRefEffect.cjs 780 B
packages/react-simplikit/dist/hooks/useRefEffect/useRefEffect.mjs 753 B
packages/react-simplikit/dist/hooks/useSafeAreaInset/useSafeAreaInset.cjs 942 B
packages/react-simplikit/dist/hooks/useSafeAreaInset/useSafeAreaInset.mjs 927 B
packages/react-simplikit/dist/hooks/useScrollDirection/useScrollDirection.cjs 955 B
packages/react-simplikit/dist/hooks/useScrollDirection/useScrollDirection.mjs 944 B
packages/react-simplikit/dist/hooks/useSet/useSet.cjs 1.03 kB
packages/react-simplikit/dist/hooks/useSet/useSet.mjs 1 kB
packages/react-simplikit/dist/hooks/useStorageState/storage.cjs 543 B
packages/react-simplikit/dist/hooks/useStorageState/storage.mjs 527 B
packages/react-simplikit/dist/hooks/useStorageState/useStorageState.cjs 966 B
packages/react-simplikit/dist/hooks/useStorageState/useStorageState.mjs 957 B
packages/react-simplikit/dist/hooks/useThrottle/throttle.cjs 431 B
packages/react-simplikit/dist/hooks/useThrottle/throttle.mjs 422 B
packages/react-simplikit/dist/hooks/useThrottle/useThrottle.cjs 864 B
packages/react-simplikit/dist/hooks/useThrottle/useThrottle.mjs 838 B
packages/react-simplikit/dist/hooks/useThrottledCallback/useThrottledCallback.cjs 1.02 kB
packages/react-simplikit/dist/hooks/useThrottledCallback/useThrottledCallback.mjs 993 B
packages/react-simplikit/dist/hooks/useTimeout/useTimeout.cjs 627 B
packages/react-simplikit/dist/hooks/useTimeout/useTimeout.mjs 600 B
packages/react-simplikit/dist/hooks/useToggle/useToggle.cjs 524 B
packages/react-simplikit/dist/hooks/useToggle/useToggle.mjs 506 B
packages/react-simplikit/dist/hooks/useVisibilityEvent/useVisibilityEvent.cjs 692 B
packages/react-simplikit/dist/hooks/useVisibilityEvent/useVisibilityEvent.mjs 674 B
packages/react-simplikit/dist/hooks/useVisualViewport/useVisualViewport.cjs 1.24 kB
packages/react-simplikit/dist/hooks/useVisualViewport/useVisualViewport.mjs 1.22 kB
packages/react-simplikit/dist/utils/buildContext/buildContext.cjs 809 B
packages/react-simplikit/dist/utils/buildContext/buildContext.mjs 788 B
packages/react-simplikit/dist/utils/disableBodyScrollLock/disableBodyScrollLock.cjs 677 B
packages/react-simplikit/dist/utils/disableBodyScrollLock/disableBodyScrollLock.mjs 668 B
packages/react-simplikit/dist/utils/enableBodyScrollLock/enableBodyScrollLock.cjs 672 B
packages/react-simplikit/dist/utils/enableBodyScrollLock/enableBodyScrollLock.mjs 662 B
packages/react-simplikit/dist/utils/getKeyboardHeight/getKeyboardHeight.cjs 609 B
packages/react-simplikit/dist/utils/getKeyboardHeight/getKeyboardHeight.mjs 602 B
packages/react-simplikit/dist/utils/getSafeAreaInset/getSafeAreaInset.cjs 902 B
packages/react-simplikit/dist/utils/getSafeAreaInset/getSafeAreaInset.mjs 893 B
packages/react-simplikit/dist/utils/isAndroid/isAndroid.cjs 543 B
packages/react-simplikit/dist/utils/isAndroid/isAndroid.mjs 534 B
packages/react-simplikit/dist/utils/isIOS/isIOS.cjs 753 B
packages/react-simplikit/dist/utils/isIOS/isIOS.mjs 746 B
packages/react-simplikit/dist/utils/isKeyboardVisible/isKeyboardVisible.cjs 431 B
packages/react-simplikit/dist/utils/isKeyboardVisible/isKeyboardVisible.mjs 419 B
packages/react-simplikit/dist/utils/isServer/isServer.cjs 381 B
packages/react-simplikit/dist/utils/isServer/isServer.mjs 379 B
packages/react-simplikit/dist/utils/mergeProps/mergeProps.cjs 671 B
packages/react-simplikit/dist/utils/mergeProps/mergeProps.mjs 670 B
packages/react-simplikit/dist/utils/mergeRefs/mergeRefs.cjs 616 B
packages/react-simplikit/dist/utils/mergeRefs/mergeRefs.mjs 614 B
packages/react-simplikit/dist/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.cjs 1.12 kB
packages/react-simplikit/dist/utils/subscribeKeyboardHeight/subscribeKeyboardHeight.mjs 1.1 kB

compressed-size-action

@hyesungoh
hyesungoh marked this pull request as ready for review September 4, 2026 12:01
@hyesungoh
hyesungoh requested a review from mnxmnz as a code owner September 4, 2026 12:01
Copilot AI lite review requested due to automatic review settings September 4, 2026 12:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The new hooks follow existing patterns, include SSR/StrictMode considerations, and add comprehensive automated test coverage and documentation for the new public APIs.

Pull request overview

Adds two new value-shaped hooks—useDebouncedValue and useThrottledValue—to complement the existing callback-shaped debounce/throttle hooks in react-simplikit. These hooks let callers keep owning state while consuming a delayed (debounced/throttled) copy for driving expensive renders or derived inputs.

Changes:

  • Export new public APIs useDebouncedValue and useThrottledValue from the package root.
  • Implement both hooks with SSR-safe initialization, StrictMode-friendly effect behavior, and full option support (leading/trailing).
  • Add comprehensive tests, hook docs (EN + KO), skill catalog entries, and a changeset.
File summaries
File Description
packages/react-simplikit/src/index.ts Exports the two new hooks from the public entrypoint.
packages/react-simplikit/src/hooks/useDebouncedValue/useDebouncedValue.ts Implements useDebouncedValue using useDebounce and a reference/settled guard.
packages/react-simplikit/src/hooks/useDebouncedValue/useDebouncedValue.spec.ts Tests debounce timing, options, SSR safety, StrictMode behavior, and unmount cancelation.
packages/react-simplikit/src/hooks/useDebouncedValue/useDebouncedValue.md Adds English API docs for useDebouncedValue.
packages/react-simplikit/src/hooks/useDebouncedValue/ko/useDebouncedValue.md Adds Korean API docs for useDebouncedValue.
packages/react-simplikit/src/hooks/useDebouncedValue/index.ts Re-export barrel for useDebouncedValue.
packages/react-simplikit/src/hooks/useThrottledValue/useThrottledValue.ts Implements useThrottledValue using useThrottle and a reference/settled guard.
packages/react-simplikit/src/hooks/useThrottledValue/useThrottledValue.spec.ts Tests throttle window behavior across leading/trailing options, SSR safety, StrictMode, and unmount cancelation.
packages/react-simplikit/src/hooks/useThrottledValue/useThrottledValue.md Adds English API docs for useThrottledValue.
packages/react-simplikit/src/hooks/useThrottledValue/ko/useThrottledValue.md Adds Korean API docs for useThrottledValue.
packages/react-simplikit/src/hooks/useThrottledValue/index.ts Re-export barrel for useThrottledValue.
packages/plugin/skills/react-simplikit/SKILL.md Adds both hooks to the skill catalog table.
packages/plugin/skills/react-simplikit/references/useDebouncedValue.md Adds skill reference page for useDebouncedValue.
packages/plugin/skills/react-simplikit/references/useThrottledValue.md Adds skill reference page for useThrottledValue.
.changeset/add-debounced-throttled-value.md Declares a minor release for the new hook exports.
Review details
  • Files reviewed: 15/15 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codecov-commenter

codecov-commenter commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (52ed163) to head (bebc20b).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##              main      #471   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           67        69    +2     
  Lines         2169      2227   +58     
  Branches       701       716   +15     
=========================================
+ Hits          2169      2227   +58     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@hyesungoh
hyesungoh force-pushed the feat/debounced-throttled-value branch from 30e9676 to d56eb97 Compare September 7, 2026 02:42
Base automatically changed from fix/throttle-trailing-window to main September 7, 2026 08:41
@hyesungoh
hyesungoh force-pushed the feat/debounced-throttled-value branch from d56eb97 to bebc20b Compare September 7, 2026 08:47
@hyesungoh
hyesungoh merged commit edddd4b into main Sep 7, 2026
19 checks passed
@hyesungoh
hyesungoh deleted the feat/debounced-throttled-value branch September 7, 2026 08:53
@github-actions github-actions Bot mentioned this pull request Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants