Skip to content

Instantly share code, notes, and snippets.

@jamiebuilds
Last active June 8, 2024 10:45
Show Gist options
  • Save jamiebuilds/47b227913ec2dd76f6d7ba2d686a0109 to your computer and use it in GitHub Desktop.
Save jamiebuilds/47b227913ec2dd76f6d7ba2d686a0109 to your computer and use it in GitHub Desktop.
import { Dispatch, SetStateAction, useCallback, useState } from "react";
/**
* Returns a stateful value, its previous value, and a function to update it.
*/
export function useStateWithPrev<S>(
initialState: S | (() => S),
initialPrevState: S | (() => S)
): [prevState: S, state: S, setState: Dispatch<SetStateAction<S>>];
// convenience overload when second argument is omitted
/**
* Returns a stateful value, its previous value, and a function to update it.
*/
export function useStateWithPrev<S>(
initialState: S | (() => S)
): [prevState: S | void, state: S, setState: Dispatch<SetStateAction<S>>];
// convenience overload when the first two arguments are omitted
/**
* Returns a stateful value, its previous value, and a function to update it.
*/
export function useStateWithPrev<S = undefined>(): [
prevState: S | void,
state: S | void,
setState: Dispatch<SetStateAction<S>>
];
/**
* Returns a stateful value, its previous value, and a function to update it.
*/
export function useStateWithPrev<S>(
initialState?: S | (() => S) | void,
initialPrevState?: S | (() => S) | void
): [
prevState: S | void,
state: S | void,
setState: Dispatch<SetStateAction<S>>
] {
let [[prevState, state], setStateInner] = useState<[S | void, S | void]>(
() => {
let prevState =
typeof initialPrevState === "function"
? // @ts-expect-error
initialPrevState()
: initialPrevState;
let state =
typeof initialState === "function"
? // @ts-expect-error
initialState()
: initialState;
return [prevState, state];
}
);
let setState: Dispatch<SetStateAction<S>> = useCallback((updater) => {
setStateInner(([, state]) => {
let value;
if (typeof updater === "function") {
// @ts-expect-error
value = updater(state);
} else {
value = updater;
}
return [state, value];
});
}, []);
return [prevState, state, setState];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment