Skip to content

Instantly share code, notes, and snippets.

@sarakusha
Last active March 10, 2022 07:12
Show Gist options
  • Save sarakusha/2fc9d1d4d3e732d3ac890993a9c80a4a to your computer and use it in GitHub Desktop.
Save sarakusha/2fc9d1d4d3e732d3ac890993a9c80a4a to your computer and use it in GitHub Desktop.
Can be used in custom hooks and allows you to get the current state (states) from the `useState` hook without adding a dependency.
import { Dispatch, SetStateAction } from 'react';
type Setter<S> = Dispatch<SetStateAction<S>>;
/**
* Can be used in custom hooks and allows you to get the current state from the `useState` hook
* without adding a dependency.
* @param setter
* @example
* ```
* const [value, setValue] = useState(0);
* const submitHandler = useCallback(async e => {
* // Get the current state with a setter.
* const currentValue = await getStateAsync(setValue);
* // …
* }, []) // No `value` dependency!
* ```
*/
const getStateAsync = <S>(setter: Setter<S>): Promise<S> =>
new Promise<S>(resolve => {
setter(prevState => {
resolve(prevState);
return prevState;
});
});
export default getStateAsync;
export function getStatesAsync<S1, S2, S3, S4, S5, S6, S7, S8, S9, S10>(
setter1: Setter<S1>,
setter2: Setter<S2>,
setter3: Setter<S3>,
setter4: Setter<S4>,
setter5: Setter<S5>,
setter6: Setter<S6>,
setter7: Setter<S7>,
setter8: Setter<S8>,
setter9: Setter<S9>,
setter10: Setter<S10>
): Promise<[S1, S2, S3, S4, S5, S6, S7, S8, S9, S10]>;
export function getStatesAsync<S1, S2, S3, S4, S5, S6, S7, S8, S9>(
setter1: Setter<S1>,
setter2: Setter<S2>,
setter3: Setter<S3>,
setter4: Setter<S4>,
setter5: Setter<S5>,
setter6: Setter<S6>,
setter7: Setter<S7>,
setter8: Setter<S8>,
setter9: Setter<S9>
): Promise<[S1, S2, S3, S4, S5, S6, S7, S8, S9]>;
export function getStatesAsync<S1, S2, S3, S4, S5, S6, S7, S8>(
setter1: Setter<S1>,
setter2: Setter<S2>,
setter3: Setter<S3>,
setter4: Setter<S4>,
setter5: Setter<S5>,
setter6: Setter<S6>,
setter7: Setter<S7>,
setter8: Setter<S8>
): Promise<[S1, S2, S3, S4, S5, S6, S7, S8]>;
export function getStatesAsync<S1, S2, S3, S4, S5, S6, S7>(
setter1: Setter<S1>,
setter2: Setter<S2>,
setter3: Setter<S3>,
setter4: Setter<S4>,
setter5: Setter<S5>,
setter6: Setter<S6>,
setter7: Setter<S7>
): Promise<[S1, S2, S3, S4, S5, S6, S7]>;
export function getStatesAsync<S1, S2, S3, S4, S5, S6>(
setter1: Setter<S1>,
setter2: Setter<S2>,
setter3: Setter<S3>,
setter4: Setter<S4>,
setter5: Setter<S5>,
setter6: Setter<S6>
): Promise<[S1, S2, S3, S4, S5, S6]>;
export function getStatesAsync<S1, S2, S3, S4, S5>(
setter1: Setter<S1>,
setter2: Setter<S2>,
setter3: Setter<S3>,
setter4: Setter<S4>,
setter5: Setter<S5>
): Promise<[S1, S2, S3, S4, S5]>;
export function getStatesAsync<S1, S2, S3, S4>(
setter1: Setter<S1>,
setter2: Setter<S2>,
setter3: Setter<S3>,
setter4: Setter<S4>
): Promise<[S1, S2, S3, S4]>;
export function getStatesAsync<S1, S2, S3>(
setter1: Setter<S1>,
setter2: Setter<S2>,
setter3: Setter<S3>
): Promise<[S1, S2, S3]>;
export function getStatesAsync<S1, S2>(setter1: Setter<S1>, setter2: Setter<S2>): Promise<[S1, S2]>;
export function getStatesAsync<S>(setter1: Setter<S>): Promise<[S]>;
/**
* Get set of current states
* @param setters
* @example
* ```
* const [value1, setValue1] = useState(0);
* const [value2, setValue2] = useState('initial');
* // …
* const [valueN, setValueN] = useState(N);
* const submitHandler = useCallback(async e => {
* const [v1, v2, …, vN] = await getStatesAsync(setValue1, setValue2, …, setValueN);
* const res = await fetch(url, {
* method: 'POST',
* body: JSON.stringify({ v1, v2, …, vN }),
* })
* // …
* }, []);
* ```
*/
export function getStatesAsync(...setters: Setter<unknown>[]): Promise<unknown[]> {
return Promise.all(setters.map(setter => getStateAsync(setter)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment