Skip to content

Instantly share code, notes, and snippets.

@david-arteaga
Created September 20, 2020 04:32
Show Gist options
  • Save david-arteaga/38b7f71033e23edc3821705fbffe4e8d to your computer and use it in GitHub Desktop.
Save david-arteaga/38b7f71033e23edc3821705fbffe4e8d to your computer and use it in GitHub Desktop.
[useSpreadState] #react #typescript #hooks
import React from 'react';
import { useState, useCallback } from 'react';
export type SetSpreadStateFn<T> = (
s: Partial<T> | ((ns: T) => Partial<T>),
) => void;
export type SpreadStateReturnType<T> = [T, SetSpreadStateFn<T>];
export default function useSpreadState<State>(
initialValue: State | (() => State),
): SpreadStateReturnType<State> {
const [state, setState] = useState(initialValue);
const spreadSetState = useCallback(
newState => {
if (typeof newState === 'function') {
setState(previousState => {
const newStateValue = newState(previousState);
return {
...previousState,
...newStateValue,
};
});
} else {
setState(previousState => ({ ...previousState, ...newState }));
}
},
[setState],
);
const ret: SpreadStateReturnType<State> = [state, spreadSetState];
const memoed = React.useMemo(() => ret, ret);
return memoed;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment