postiz/libraries/react-shared-libraries/src/helpers/use.state.callback.ts

25 lines
881 B
TypeScript

import { useCallback, useEffect, useRef, useState } from 'react';
export function useStateCallback<T>(
initialState: T
): [T, (state: T, cb?: (state: T) => void) => void] {
const [state, setState] = useState(initialState);
const cbRef = useRef<((state: T) => void) | undefined>(undefined); // init mutable ref container for callbacks
const setStateCallback = useCallback((state: T, cb?: (state: T) => void) => {
cbRef.current = cb; // store current, passed callback in ref
setState(state);
}, []); // keep object reference stable, exactly like `useState`
useEffect(() => {
// cb.current is `undefined` on initial render,
// so we only invoke callback on state *updates*
if (cbRef.current) {
cbRef.current(state);
cbRef.current = undefined; // reset callback after execution
}
}, [state]);
return [state, setStateCallback];
}