Skip to content

Instantly share code, notes, and snippets.

@paoloricciuti
Created January 21, 2022 08:46
Show Gist options
  • Select an option

  • Save paoloricciuti/0b44dee77379c3bb0c1ae97097584b92 to your computer and use it in GitHub Desktop.

Select an option

Save paoloricciuti/0b44dee77379c3bb0c1ae97097584b92 to your computer and use it in GitHub Desktop.
useCallbackState.ts
import { useEffect, useRef, useState } from "react";
type CallBackType<T> = (updatedValue: T) => void;
type SetStateType<T> = T | ((prev: T) => T);
type RetType = <T>(
initialValue: T | (() => T)
) => [T, (newValue: SetStateType<T>, callback?: CallBackType<T>) => void];
const useCallbackState: RetType = <T>(initialValue: T | (() => T)) => {
const [state, _setState] = useState<T>(initialValue);
const callbackQueue = useRef<CallBackType<T>[]>([]);
useEffect(() => {
callbackQueue.current.forEach((cb) => cb(state));
callbackQueue.current = [];
}, [state]);
const setState = (newValue: SetStateType<T>, callback?: CallBackType<T>) => {
_setState(newValue);
if (callback && typeof callback === "function") {
callbackQueue.current.push(callback);
}
};
return [state, setState];
};
export default useCallbackState;
@fentonius
Copy link

this is the preferred version, works perfectly. Simplified my code immensely. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment