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
10 changes: 7 additions & 3 deletions src/hooks/useDelayState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import raf from '../raf';
import useEvent from './useEvent';

export type DelayConfig =
{ frame: number; ms?: never } | { frame?: never; ms: number };
| { frame: number; ms?: never }
| { frame?: never; ms: number };

export type SetDelayState<T> = (
nextValue: React.SetStateAction<T>,
Expand Down Expand Up @@ -37,8 +38,11 @@ export default function useDelayState<T>(
}
});

const setDelayValue = useEvent<SetDelayState<T>>(
(nextValue, immediatelyOrDelay) => {
const setDelayValue = useEvent(
(
nextValue: React.SetStateAction<T>,
immediatelyOrDelay?: boolean | DelayConfig,
) => {
const delayConfig = immediatelyOrDelay || { frame: 1 };
cancelPending();

Expand Down
59 changes: 40 additions & 19 deletions src/hooks/useEvent.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
import * as React from 'react';

const useEvent = <T extends ((...args: any[]) => any) | undefined>(
callback: T,
): undefined extends T
? (
...args: Parameters<NonNullable<T>>
) => ReturnType<NonNullable<T>> | undefined
: T => {
const fnRef = React.useRef<T | undefined>(callback);
fnRef.current = callback;

const memoFn = React.useCallback(
(...args: any[]) => fnRef.current?.(...args),
[],
);

return memoFn;
};
import React from 'react';
import { useState } from 'react';

const useIsomorphicLayoutEffect =
typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;

type StableHandler<This, Args extends unknown[], Result> = (
this: This,
...args: Args
) => Result;

function useEvent<This, Args extends unknown[], Result>(
fn: StableHandler<This, Args, Result>,
): StableHandler<This, Args, Result>;

function useEvent<
This = unknown,
Args extends unknown[] = [],
Result = undefined,
>(
fn?: StableHandler<This, Args, Result>,
): StableHandler<This, Args, Result | undefined>;

function useEvent<This, Args extends unknown[], Result>(
callback?: StableHandler<This, Args, Result>,
) {
Comment thread
li-jia-nan marked this conversation as resolved.
const fnRef = React.useRef<StableHandler<This, Args, Result>>(callback);
Comment thread
li-jia-nan marked this conversation as resolved.

useIsomorphicLayoutEffect(() => {
fnRef.current = callback;
}, [callback]);

const [stableHandler] = useState(() => {
return function (this: This, ...args: Args) {
return fnRef.current?.apply(this, args);
};
});

return stableHandler;
Comment thread
li-jia-nan marked this conversation as resolved.
}

export default useEvent;
Loading