Skip to content

Commit

Permalink
fix: make useDebounceCallback and useRafCallback return proper fns (
Browse files Browse the repository at this point in the history
#100)

Previous version returned wrapped function that has no name and 0
length, meaning that they do not expect arguments.

Current version sets length to same value as original function.
  • Loading branch information
xobotyi authored Jun 2, 2021
1 parent 509ec73 commit 1dcb083
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 33 deletions.
7 changes: 7 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ module.exports = {
'react/prop-types': 'off',
},
},
{
files: ['src/**/__tests__/*.ts'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
},
{
files: ['*.md'],
extends: ['plugin:mdx/recommended', 'prettier'],
Expand Down
16 changes: 16 additions & 0 deletions src/useDebounceCallback/__tests__/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ describe('useDebounceCallback', () => {
expect(result.error).toBeUndefined();
});

it('should return function same length and wrapped name', () => {
let { result } = renderHook(() =>
useDebounceCallback((_a: any, _b: any, _c: any) => {}, 200, [])
);

expect(result.current.length).toBe(3);
expect(result.current.name).toBe(`anonymous__debounced__200`);

function testFn(_a: any, _b: any, _c: any) {}

result = renderHook(() => useDebounceCallback(testFn, 100, [])).result;

expect(result.current.length).toBe(3);
expect(result.current.name).toBe(`testFn__debounced__100`);
});

it('should return new callback if delay is changed', () => {
const { result, rerender } = renderHook(
({ delay }) => useDebounceCallback(() => {}, delay, []),
Expand Down
16 changes: 12 additions & 4 deletions src/useDebounceCallback/useDebounceCallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,26 @@ export function useDebounceCallback<T extends (...args: any[]) => any>(
deps: DependencyList
): (...args: Parameters<T>) => void {
const timeout = useRef<ReturnType<typeof setTimeout>>();

return useMemo(
() =>
(...args: Parameters<T>): void => {
() => {
// eslint-disable-next-line func-names
const debounced = function (...args: Parameters<T>): void {
if (timeout.current) clearTimeout(timeout.current);

timeout.current = setTimeout(() => {
timeout.current = undefined;

cb(...args);
}, delay);
},
};

Object.defineProperties(debounced, {
length: { value: cb.length },
name: { value: `${cb.name || 'anonymous'}__debounced__${delay}` },
});

return debounced;
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[delay, ...deps]
);
Expand Down
16 changes: 15 additions & 1 deletion src/useRafCallback/__tests__/dom.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { renderHook } from '@testing-library/react-hooks/dom';
import { useRafCallback } from '../..';
import { useDebounceCallback, useRafCallback } from '../..';

describe('useRafCallback', () => {
const raf = global.requestAnimationFrame;
Expand Down Expand Up @@ -27,6 +27,20 @@ describe('useRafCallback', () => {
renderHook(() => useRafCallback(() => {}));
});

it('should return function same length and wrapped name', () => {
let { result } = renderHook(() => useRafCallback((_a: any, _b: any, _c: any) => {}));

expect(result.current[0].length).toBe(3);
expect(result.current[0].name).toBe(`anonymous__raf`);

function testFn(_a: any, _b: any, _c: any) {}

result = renderHook(() => useRafCallback(testFn)).result;

expect(result.current[0].length).toBe(3);
expect(result.current[0].name).toBe(`testFn__raf`);
});

it('should return array of functions', () => {
const { result } = renderHook(() => useRafCallback(() => {}));

Expand Down
24 changes: 17 additions & 7 deletions src/useRafCallback/useRafCallback.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useRef } from 'react';
import { useCallback, useMemo, useRef } from 'react';
import { useSyncedRef } from '../useSyncedRef/useSyncedRef';
import { isBrowser } from '../util/const';
import { useUnmountEffect } from '../useUnmountEffect/useUnmountEffect';
Expand Down Expand Up @@ -29,17 +29,27 @@ export function useRafCallback<T extends (...args: any[]) => any>(
useUnmountEffect(cancel);

return [
useCallback((...args) => {
if (!isBrowser) return;
useMemo(() => {
const wrapped = (...args: Parameters<T>) => {
if (!isBrowser) return;

cancel();
cancel();

frame.current = requestAnimationFrame(() => {
cbRef.current(...args);
frame.current = 0;
frame.current = requestAnimationFrame(() => {
cbRef.current(...args);
frame.current = 0;
});
};

Object.defineProperties(wrapped, {
length: { value: cb.length },
name: { value: `${cb.name || 'anonymous'}__raf` },
});

return wrapped;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []),

cancel,
];
}
42 changes: 21 additions & 21 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1661,7 +1661,7 @@
"@nodelib/fs.scandir" "2.1.4"
fastq "^1.6.0"

"@npmcli/arborist@^2.3.0", "@npmcli/arborist@^2.5.0", "@npmcli/arborist@^2.6.0":
"@npmcli/arborist@^2.3.0", "@npmcli/arborist@^2.5.0", "@npmcli/arborist@^2.6.1":
version "2.6.1"
resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-2.6.1.tgz#bdbd1311cc857583ffc85f4d3f24a50683303dda"
integrity sha512-OOlntFIOAo7RplEQaYXlA5U5NXE+EwZtnTCsit4Wtme5+llGiea6GBytuV8dOzdPMPlNx3fQQjBUE9E8k76yjQ==
Expand Down Expand Up @@ -5651,9 +5651,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=

electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.723:
version "1.3.742"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz#7223215acbbd3a5284962ebcb6df85d88b95f200"
integrity sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q==
version "1.3.743"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.743.tgz#fcec24d6d647cb84fd796b42caa1b4039a180894"
integrity sha512-K2wXfo9iZQzNJNx67+Pld0DRF+9bYinj62gXCdgPhcu1vidwVuLPHQPPFnCdO55njWigXXpfBiT90jGUPbw8Zg==

element-resize-detector@^1.2.2:
version "1.2.2"
Expand Down Expand Up @@ -6698,10 +6698,10 @@ format@^0.2.0:
resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=

forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==

fragment-cache@^0.2.1:
version "0.2.1"
Expand Down Expand Up @@ -8900,10 +8900,10 @@ libnpmdiff@^2.0.4:
pacote "^11.3.0"
tar "^6.1.0"

libnpmexec@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/libnpmexec/-/libnpmexec-1.1.1.tgz#aa510cc74612cac3945f7e2fd2ac4c650fa7ef66"
integrity sha512-uw6H2dzC6F6fdq7lAxfzXPimHCJ3/g6ycFKcv2Q2QXuNZ94EDmNPpMO6f4mwiC5F6Lyy/WK0IL7AZwRhmSvUdQ==
libnpmexec@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/libnpmexec/-/libnpmexec-1.2.0.tgz#ab0294ab63bb599b3ac6921129b7a706d4d56da2"
integrity sha512-LkxnH2wsMUI4thsgUK0r+EFZ5iCjKlp21J68dFY7AzD5uaaIPqO3lqVvYbyl1Umz1R4rY9t3vFa1fF3hzo6Y2Q==
dependencies:
"@npmcli/arborist" "^2.3.0"
"@npmcli/ci-detect" "^1.3.0"
Expand Down Expand Up @@ -10045,11 +10045,11 @@ npm-user-validate@^1.0.1:
integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==

npm@^7.0.0:
version "7.15.0"
resolved "https://registry.yarnpkg.com/npm/-/npm-7.15.0.tgz#85f0ff4ff222c01a2cc0164cf5d81c5a24994894"
integrity sha512-GIXNqy3obii54oPF0gbcBNq4aYuB/Ovuu/uYp1eS4nij2PEDMnoOh6RoSv2MDvAaB4a+JbpX/tjDxLO7JAADgQ==
version "7.15.1"
resolved "https://registry.yarnpkg.com/npm/-/npm-7.15.1.tgz#19fea8999872e05a1b9b73851c91f92c6d08f9fc"
integrity sha512-sPk+GrqawshbG3T81r2QvvSxSQXBFWyn5NGLacf87l+/odi2ZRHkWdLrg304Lw0DrwwIIaGxUjp0FJXaMtIErQ==
dependencies:
"@npmcli/arborist" "^2.6.0"
"@npmcli/arborist" "^2.6.1"
"@npmcli/ci-detect" "^1.2.0"
"@npmcli/config" "^2.2.0"
"@npmcli/run-script" "^1.8.5"
Expand All @@ -10074,7 +10074,7 @@ npm@^7.0.0:
leven "^3.1.0"
libnpmaccess "^4.0.2"
libnpmdiff "^2.0.4"
libnpmexec "^1.1.1"
libnpmexec "^1.2.0"
libnpmfund "^1.1.0"
libnpmhook "^6.0.2"
libnpmorg "^2.0.2"
Expand Down Expand Up @@ -11013,11 +11013,11 @@ protocols@^1.1.0, protocols@^1.4.0:
integrity sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==

proxy-addr@~2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==
version "2.0.7"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
dependencies:
forwarded "~0.1.2"
forwarded "0.2.0"
ipaddr.js "1.9.1"

prr@~1.0.1:
Expand Down

0 comments on commit 1dcb083

Please sign in to comment.