However, it "clicked" with me when I saw how they use their usePromise hook (to me it seems like their useAsyncExtendedState hook is only really useful in conjunction with their usePromise hook). That is, it is extremely common in React to call some remote API, then update the state when the Promise resolves. You also have a common set of things you want to handle: showing that the request is still pending, handling an error, updating a part of the state with some subset of the response object when the Promise resolves, etc.
It's very possible to do this in React without these custom hooks, but you'll usually find you have top-level state variables in your component that mirror the success/error/pending states. You need to do that all over the place.
Using these custom hooks makes it easy and consistent to make these remote calls but handling the stuff about the remote Promise request is essentially "contained" by the result of usePromise. Seems like a really nice, clean way to get consistency across remote calls in all your components.
const shallowMergeReducer = <T extends {}>(state: T, action: Partial<T>): T => Object.freeze({
...state,
...action,
})
It ends up looking a lot like the "setExtendedState" function in the article.Often I'll throw in a few helper functions in a useMemo, too, and then provide the whole thing through Context. It's like a mini-Redux for some section of the app.
setState((previousState) => ({...previousState, foo: false}))
({ contact: { address: "" } })
as opposed to
({ ...prev, contact: { ...prev.contact, address: "" } })
Given the way hooks are structured, if I want to use both `setState` and `extendState` in a `useCallback`, I'd need to pass both to the dependency array, which is just extra effort (which defeats the purpose of the syntactic sugar imo).