Skip to content

Instantly share code, notes, and snippets.

@alanhr
Last active August 10, 2022 12:50
Show Gist options
  • Save alanhr/cd12e7d5475ecaf0c950587c97877bb5 to your computer and use it in GitHub Desktop.
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

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