Skip to content

feat(useCallbackOnce): rename useCallbackOncePerRender to useCallbackOnce - #545

Merged
hyesungoh merged 3 commits into
v1-basefrom
feat/use-callback-once
Oct 7, 2026
Merged

hyesungoh merged 3 commits into
v1-basefrom
feat/use-callback-once

Conversation

@hyesungoh

Copy link
Copy Markdown
Member

Overview

Closes #542

  • Add useCallbackOnce. It has the same signature and behavior as useCallbackOncePerRender, whose name suggests the callback runs once per render when it actually runs once until deps change.
  • useCallbackOncePerRender is now a deprecated alias of useCallbackOnce. It is the same function, so existing calls keep working, and editors show it as deprecated.
  • The JSDoc now says the callback runs once until deps change, types callback as F because it also receives the returned function's arguments, and adds userId to the second example's dependency list.
  • The deps description no longer reads as if a change runs the callback; a change lets the returned function run it once more. The return value is documented as (...args: Parameters<F>) => void with a reference that never changes, which is why the example needs userId in its dependency list. The Spanish pages drop the mistranslation "memorizada" along the way.
  • Deprecated exports are now supported by the docs and skill tooling, which previously rejected any @deprecated tag:
    • docs:gen renders the @deprecated text as a warning block at the top of the page.
    • The generated agent skill lists deprecated exports in a separate Deprecated table with their replacement, instead of the regular tables.
    • test:skill checks that the Deprecated table matches the @deprecated exports and that the Common needs table names none of them. A @deprecated tag must name its replacement in backticks.
  • The translated pages for the new hook are added, and the old hook's translated pages show the deprecation notice.

Tests

The tests moved to useCallbackOnce.test.ts unchanged. One added test checks that useCallbackOncePerRender is the same function, which also keeps the alias file covered. The tooling changes are covered in the .scripts specs.

Checklist

  • Did you write the test code?
  • Have you run yarn run fix to format and lint the code and docs? (yarn test passes)
  • 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 30, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d1b0681

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 30, 2026 •

Copy link
Copy Markdown
Contributor

Size Change: +589 B (+0.51%)

Total Size: 115 kB

📦 View Changed
Filename Size Change
packages/react-simplikit/dist/hooks/useCallbackOnce/useCallbackOnce.cjs 901 B +901 B (new file) 🆕
packages/react-simplikit/dist/hooks/useCallbackOnce/useCallbackOnce.mjs 873 B +873 B (new file) 🆕
packages/react-simplikit/dist/hooks/useCallbackOnce/useCallbackOncePerRender.cjs 195 B +195 B (new file) 🆕
packages/react-simplikit/dist/hooks/useCallbackOnce/useCallbackOncePerRender.mjs 197 B +197 B (new file) 🆕
packages/react-simplikit/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.cjs 0 B -815 B (removed) 🏆
packages/react-simplikit/dist/hooks/useCallbackOncePerRender/useCallbackOncePerRender.mjs 0 B -786 B (removed) 🏆
packages/react-simplikit/dist/index.cjs 1.4 kB +15 B (+1.08%)
packages/react-simplikit/dist/index.mjs 1.01 kB +9 B (+0.89%)
ℹ️ 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 723 B
packages/react-simplikit/dist/components/SwitchCase/SwitchCase.mjs 721 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 887 B
packages/react-simplikit/dist/hooks/useBodyScrollLock/useBodyScrollLock.mjs 863 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/useConditionalEffect/useConditionalEffect.cjs 980 B
packages/react-simplikit/dist/hooks/useConditionalEffect/useConditionalEffect.mjs 959 B
packages/react-simplikit/dist/hooks/useControlledState/useControlledState.cjs 1.04 kB
packages/react-simplikit/dist/hooks/useControlledState/useControlledState.mjs 1.03 kB
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 1.28 kB
packages/react-simplikit/dist/hooks/useDebounce/useDebounce.mjs 1.26 kB
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/useDebouncedValue/useDebouncedValue.cjs 1.21 kB
packages/react-simplikit/dist/hooks/useDebouncedValue/useDebouncedValue.mjs 1.18 kB
packages/react-simplikit/dist/hooks/useDoubleClick/useDoubleClick.cjs 970 B
packages/react-simplikit/dist/hooks/useDoubleClick/useDoubleClick.mjs 954 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.25 kB
packages/react-simplikit/dist/hooks/useImpressionRef/useImpressionRef.mjs 1.22 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.1 kB
packages/react-simplikit/dist/hooks/useIntersectionObserver/useIntersectionObserver.mjs 1.07 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 736 B
packages/react-simplikit/dist/hooks/useKeyboardHeight/useKeyboardHeight.mjs 717 B
packages/react-simplikit/dist/hooks/useList/useList.cjs 955 B
packages/react-simplikit/dist/hooks/useList/useList.mjs 933 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.71 kB
packages/react-simplikit/dist/hooks/useLongPress/useLongPress.mjs 1.68 kB
packages/react-simplikit/dist/hooks/useMap/useMap.cjs 762 B
packages/react-simplikit/dist/hooks/useMap/useMap.mjs 744 B
packages/react-simplikit/dist/hooks/useNetworkStatus/useNetworkStatus.cjs 1.61 kB
packages/react-simplikit/dist/hooks/useNetworkStatus/useNetworkStatus.mjs 1.59 kB
packages/react-simplikit/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.cjs 785 B
packages/react-simplikit/dist/hooks/useOutsideClickEffect/useOutsideClickEffect.mjs 755 B
packages/react-simplikit/dist/hooks/usePageVisibility/usePageVisibility.cjs 1.28 kB
packages/react-simplikit/dist/hooks/usePageVisibility/usePageVisibility.mjs 1.25 kB
packages/react-simplikit/dist/hooks/usePreservedCallback/usePreservedCallback.cjs 751 B
packages/react-simplikit/dist/hooks/usePreservedCallback/usePreservedCallback.mjs 733 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 640 B
packages/react-simplikit/dist/hooks/usePrevious/usePrevious.mjs 631 B
packages/react-simplikit/dist/hooks/useRefEffect/useRefEffect.cjs 836 B
packages/react-simplikit/dist/hooks/useRefEffect/useRefEffect.mjs 820 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 1.34 kB
packages/react-simplikit/dist/hooks/useScrollDirection/useScrollDirection.mjs 1.33 kB
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 973 B
packages/react-simplikit/dist/hooks/useStorageState/useStorageState.mjs 964 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 894 B
packages/react-simplikit/dist/hooks/useThrottle/useThrottle.mjs 871 B
packages/react-simplikit/dist/hooks/useThrottledCallback/useThrottledCallback.cjs 1.03 kB
packages/react-simplikit/dist/hooks/useThrottledCallback/useThrottledCallback.mjs 1 kB
packages/react-simplikit/dist/hooks/useThrottledValue/useThrottledValue.cjs 1.1 kB
packages/react-simplikit/dist/hooks/useThrottledValue/useThrottledValue.mjs 1.07 kB
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.54 kB
packages/react-simplikit/dist/hooks/useVisualViewport/useVisualViewport.mjs 1.53 kB
packages/react-simplikit/dist/utils/buildContext/buildContext.cjs 864 B
packages/react-simplikit/dist/utils/buildContext/buildContext.mjs 844 B
packages/react-simplikit/dist/utils/disableBodyScrollLock/disableBodyScrollLock.cjs 667 B
packages/react-simplikit/dist/utils/disableBodyScrollLock/disableBodyScrollLock.mjs 660 B
packages/react-simplikit/dist/utils/enableBodyScrollLock/enableBodyScrollLock.cjs 663 B
packages/react-simplikit/dist/utils/enableBodyScrollLock/enableBodyScrollLock.mjs 652 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 645 B
packages/react-simplikit/dist/utils/mergeProps/mergeProps.mjs 643 B
packages/react-simplikit/dist/utils/mergeRefs/mergeRefs.cjs 790 B
packages/react-simplikit/dist/utils/mergeRefs/mergeRefs.mjs 787 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 added this pull request to stack #547 September 30, 2026 02:35
@hyesungoh
hyesungoh marked this pull request as ready for review September 30, 2026 07:50
@hyesungoh
hyesungoh requested a review from mnxmnz as a code owner September 30, 2026 07:50

@mnxmnz mnxmnz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for this, the deprecation flow turned out really nice!

One small suggestion, not a blocker. On the docs site, useCallbackOncePerRender shows up right next to useCallbackOnce in the reference page and sidebar, with nothing saying it's deprecated. Maybe generateReferenceIndex could add a (deprecated) label using extractDeprecation? Totally fine as a follow-up too.

Render a JSDoc @deprecated tag as a warning block at the top of the
generated page, move deprecated exports into a separate Deprecated table
in the generated skill, and replace the blanket @deprecated ban in
verifySkill with checks that the table matches the deprecated exports and
that the Common needs table names none of them.
…Once

useCallbackOncePerRender runs the callback once until deps change, not
once per render. Add useCallbackOnce with the same signature and
behavior, and keep useCallbackOncePerRender as a deprecated alias of it.

The JSDoc now describes the actual behavior, types the callback and the
returned function from F, and lists userId in the second example's
dependencies because the returned function keeps the same reference.
…ted alias

A deprecated alias no longer has a documentation page. useCallbackOncePerRender
moves into the useCallbackOnce folder as a one-line alias, its pages are
removed, and the useCallbackOnce page says it was renamed. The docs and skill
tooling now expects a deprecated export to have no page, lists it in the
skill's Deprecated table without a link, and the old URL redirects to the
new page.
@hyesungoh
hyesungoh force-pushed the feat/use-callback-once branch from 637fa38 to d1b0681 Compare October 7, 2026 08:52
@hyesungoh

Copy link
Copy Markdown
Member Author

@mnxmnz Thanks! I went one step further and removed the old-name page entirely, so nothing deprecated shows up in the sidebar or the reference page anymore. The useCallbackOnce page now says it was renamed, and the old URL redirects to it.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (15aea8a) to head (d1b0681).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           v1-base      #545   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           69        70    +1     
  Lines         2280      2282    +2     
  Branches       735       735           
=========================================
+ Hits          2280      2282    +2     
🚀 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 merged commit 9d16479 into v1-base Oct 7, 2026
19 checks passed
@hyesungoh
hyesungoh deleted the feat/use-callback-once branch October 7, 2026 09:08
@hyesungoh hyesungoh linked an issue Oct 8, 2026 that may be closed by this pull request
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.

Rename useCallbackOncePerRender to useCallbackOnce

3 participants