Skip to content

Instantly share code, notes, and snippets.

@alanhr
Last active August 10, 2022 12:50
Show Gist options
  • Select an option

  • Save alanhr/cd12e7d5475ecaf0c950587c97877bb5 to your computer and use it in GitHub Desktop.

Select an option

Save alanhr/cd12e7d5475ecaf0c950587c97877bb5 to your computer and use it in GitHub Desktop.
Show crazy code
import { useEffect, useState } from 'react'
interface HookResultIdleState {
state: 'idle'
}
interface HookResultLoadingState {
state: 'loading'
}
interface HookResultFailedState<E> {
state: 'failed'
error: E
}
interface HookResultSuccessState<T> {
state: 'success'
data: T
}
export type HookResultState = 'idle' | 'loading' | 'failed' | 'success'
export type HookResult<T, E = Error> =
| HookResultLoadingState
| HookResultIdleState
| HookResultSuccessState<T>
| HookResultFailedState<E>
type Props = {
loading: boolean
}
type UseResultState<T, E> = HookResult<T, E> & {
setSuccess(data: T): void
setFailed(err: E): void
}
export const useResultState = <T, E = Error>({
loading,
}: Props): UseResultState<T, E> => {
const [state, setState] = useState<HookResultState>('idle')
const [data, setData] = useState<T>()
const [error, setError] = useState<E>()
useEffect(() => {
if (loading) {
setState('loading')
}
}, [loading])
const setSuccess = (data: T) => {
setState('success')
setData(data)
}
const setFailed = (err: E) => {
setState('failed')
setError(err)
}
switch (state) {
case 'success':
return { setFailed, setSuccess, state, data: data as T }
case 'failed':
return { setFailed, setSuccess, state, error: error as E }
default:
return { setFailed, setSuccess, state }
}
}
@inodaf
Copy link
Copy Markdown

inodaf commented Aug 10, 2022

Awesome work! ๐ŸŽ‰
It would be nice if you could add some usage examples.

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